1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/view/public/nsView.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,467 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef nsView_h__ 1.10 +#define nsView_h__ 1.11 + 1.12 +#include "nsCoord.h" 1.13 +#include "nsRect.h" 1.14 +#include "nsPoint.h" 1.15 +#include "nsRegion.h" 1.16 +#include "nsCRT.h" 1.17 +#include "nsWidgetInitData.h" // for nsWindowType 1.18 +#include "nsIWidgetListener.h" 1.19 +#include "mozilla/EventForwards.h" 1.20 + 1.21 +class nsViewManager; 1.22 +class nsIWidget; 1.23 +class nsIFrame; 1.24 + 1.25 +// Enumerated type to indicate the visibility of a layer. 1.26 +// hide - the layer is not shown. 1.27 +// show - the layer is shown irrespective of the visibility of 1.28 +// the layer's parent. 1.29 +enum nsViewVisibility { 1.30 + nsViewVisibility_kHide = 0, 1.31 + nsViewVisibility_kShow = 1 1.32 +}; 1.33 + 1.34 +// Public view flags 1.35 + 1.36 +// Indicates that the view is using auto z-indexing 1.37 +#define NS_VIEW_FLAG_AUTO_ZINDEX 0x0004 1.38 + 1.39 +// Indicates that the view is a floating view. 1.40 +#define NS_VIEW_FLAG_FLOATING 0x0008 1.41 + 1.42 +//---------------------------------------------------------------------- 1.43 + 1.44 +/** 1.45 + * View interface 1.46 + * 1.47 + * Views are NOT reference counted. Use the Destroy() member function to 1.48 + * destroy a view. 1.49 + * 1.50 + * The lifetime of the view hierarchy is bounded by the lifetime of the 1.51 + * view manager that owns the views. 1.52 + * 1.53 + * Most of the methods here are read-only. To set the corresponding properties 1.54 + * of a view, go through nsViewManager. 1.55 + */ 1.56 + 1.57 +class nsView MOZ_FINAL : public nsIWidgetListener 1.58 +{ 1.59 +public: 1.60 + friend class nsViewManager; 1.61 + 1.62 + NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW 1.63 + 1.64 + /** 1.65 + * Get the view manager which "owns" the view. 1.66 + * This method might require some expensive traversal work in the future. If you can get the 1.67 + * view manager from somewhere else, do that instead. 1.68 + * @result the view manager 1.69 + */ 1.70 + nsViewManager* GetViewManager() const { return mViewManager; } 1.71 + 1.72 + /** 1.73 + * Find the view for the given widget, if there is one. 1.74 + * @return the view the widget belongs to, or null if the widget doesn't 1.75 + * belong to any view. 1.76 + */ 1.77 + static nsView* GetViewFor(nsIWidget* aWidget); 1.78 + 1.79 + /** 1.80 + * Destroy the view. 1.81 + * 1.82 + * The view destroys its child views, and destroys and releases its 1.83 + * widget (if it has one). 1.84 + * 1.85 + * Also informs the view manager that the view is destroyed by calling 1.86 + * SetRootView(NULL) if the view is the root view and calling RemoveChild() 1.87 + * otherwise. 1.88 + */ 1.89 + void Destroy(); 1.90 + 1.91 + /** 1.92 + * Called to get the position of a view. 1.93 + * The specified coordinates are relative to the parent view's origin, but 1.94 + * are in appunits of this. 1.95 + * This is the (0, 0) origin of the coordinate space established by this view. 1.96 + * @param x out parameter for x position 1.97 + * @param y out parameter for y position 1.98 + */ 1.99 + nsPoint GetPosition() const { 1.100 + NS_ASSERTION(!IsRoot() || (mPosX == 0 && mPosY == 0), 1.101 + "root views should always have explicit position of (0,0)"); 1.102 + return nsPoint(mPosX, mPosY); 1.103 + } 1.104 + 1.105 + /** 1.106 + * Called to get the dimensions and position of the view's bounds. 1.107 + * The view's bounds (x,y) are relative to the origin of the parent view, but 1.108 + * are in appunits of this. 1.109 + * The view's bounds (x,y) might not be the same as the view's position, 1.110 + * if the view has content above or to the left of its origin. 1.111 + * @param aBounds out parameter for bounds 1.112 + */ 1.113 + nsRect GetBounds() const { return mDimBounds; } 1.114 + 1.115 + /** 1.116 + * The bounds of this view relative to this view. So this is the same as 1.117 + * GetBounds except this is relative to this view instead of the parent view. 1.118 + */ 1.119 + nsRect GetDimensions() const { 1.120 + nsRect r = mDimBounds; r.MoveBy(-mPosX, -mPosY); return r; 1.121 + } 1.122 + 1.123 + /** 1.124 + * Get the offset between the coordinate systems of |this| and aOther. 1.125 + * Adding the return value to a point in the coordinate system of |this| 1.126 + * will transform the point to the coordinate system of aOther. 1.127 + * 1.128 + * The offset is expressed in appunits of |this|. So if you are getting the 1.129 + * offset between views in different documents that might have different 1.130 + * appunits per devpixel ratios you need to be careful how you use the 1.131 + * result. 1.132 + * 1.133 + * If aOther is null, this will return the offset of |this| from the 1.134 + * root of the viewmanager tree. 1.135 + * 1.136 + * This function is fastest when aOther is an ancestor of |this|. 1.137 + * 1.138 + * NOTE: this actually returns the offset from aOther to |this|, but 1.139 + * that offset is added to transform _coordinates_ from |this| to aOther. 1.140 + */ 1.141 + nsPoint GetOffsetTo(const nsView* aOther) const; 1.142 + 1.143 + /** 1.144 + * Get the offset between the origin of |this| and the origin of aWidget. 1.145 + * Adding the return value to a point in the coordinate system of |this| 1.146 + * will transform the point to the coordinate system of aWidget. 1.147 + * 1.148 + * The offset is expressed in appunits of |this|. 1.149 + */ 1.150 + nsPoint GetOffsetToWidget(nsIWidget* aWidget) const; 1.151 + 1.152 + /** 1.153 + * Takes a point aPt that is in the coordinate system of |this|'s parent view 1.154 + * and converts it to be in the coordinate system of |this| taking into 1.155 + * account the offset and any app unit per dev pixel ratio differences. 1.156 + */ 1.157 + nsPoint ConvertFromParentCoords(nsPoint aPt) const; 1.158 + 1.159 + /** 1.160 + * Called to query the visibility state of a view. 1.161 + * @result current visibility state 1.162 + */ 1.163 + nsViewVisibility GetVisibility() const { return mVis; } 1.164 + 1.165 + /** 1.166 + * Get whether the view "floats" above all other views, 1.167 + * which tells the compositor not to consider higher views in 1.168 + * the view hierarchy that would geometrically intersect with 1.169 + * this view. This is a hack, but it fixes some problems with 1.170 + * views that need to be drawn in front of all other views. 1.171 + * @result true if the view floats, false otherwise. 1.172 + */ 1.173 + bool GetFloating() const { return (mVFlags & NS_VIEW_FLAG_FLOATING) != 0; } 1.174 + 1.175 + /** 1.176 + * Called to query the parent of the view. 1.177 + * @result view's parent 1.178 + */ 1.179 + nsView* GetParent() const { return mParent; } 1.180 + 1.181 + /** 1.182 + * The view's first child is the child which is earliest in document order. 1.183 + * @result first child 1.184 + */ 1.185 + nsView* GetFirstChild() const { return mFirstChild; } 1.186 + 1.187 + /** 1.188 + * Called to query the next sibling of the view. 1.189 + * @result view's next sibling 1.190 + */ 1.191 + nsView* GetNextSibling() const { return mNextSibling; } 1.192 + 1.193 + /** 1.194 + * Set the view's frame. 1.195 + */ 1.196 + void SetFrame(nsIFrame* aRootFrame) { mFrame = aRootFrame; } 1.197 + 1.198 + /** 1.199 + * Retrieve the view's frame. 1.200 + */ 1.201 + nsIFrame* GetFrame() const { return mFrame; } 1.202 + 1.203 + /** 1.204 + * Get the nearest widget in this view or a parent of this view and 1.205 + * the offset from the widget's origin to this view's origin 1.206 + * @param aOffset - if non-null the offset from this view's origin to the 1.207 + * widget's origin (usually positive) expressed in appunits of this will be 1.208 + * returned in aOffset. 1.209 + * @return the widget closest to this view; can be null because some view trees 1.210 + * don't have widgets at all (e.g., printing), but if any view in the view tree 1.211 + * has a widget, then it's safe to assume this will not return null 1.212 + */ 1.213 + nsIWidget* GetNearestWidget(nsPoint* aOffset) const; 1.214 + 1.215 + /** 1.216 + * Create a widget to associate with this view. This variant of 1.217 + * CreateWidget*() will look around in the view hierarchy for an 1.218 + * appropriate parent widget for the view. 1.219 + * 1.220 + * @param aWidgetInitData data used to initialize this view's widget before 1.221 + * its create is called. 1.222 + * @return error status 1.223 + */ 1.224 + nsresult CreateWidget(nsWidgetInitData *aWidgetInitData = nullptr, 1.225 + bool aEnableDragDrop = true, 1.226 + bool aResetVisibility = true); 1.227 + 1.228 + /** 1.229 + * Create a widget for this view with an explicit parent widget. 1.230 + * |aParentWidget| must be nonnull. The other params are the same 1.231 + * as for |CreateWidget()|. 1.232 + */ 1.233 + nsresult CreateWidgetForParent(nsIWidget* aParentWidget, 1.234 + nsWidgetInitData *aWidgetInitData = nullptr, 1.235 + bool aEnableDragDrop = true, 1.236 + bool aResetVisibility = true); 1.237 + 1.238 + /** 1.239 + * Create a popup widget for this view. Pass |aParentWidget| to 1.240 + * explicitly set the popup's parent. If it's not passed, the view 1.241 + * hierarchy will be searched for an appropriate parent widget. The 1.242 + * other params are the same as for |CreateWidget()|, except that 1.243 + * |aWidgetInitData| must be nonnull. 1.244 + */ 1.245 + nsresult CreateWidgetForPopup(nsWidgetInitData *aWidgetInitData, 1.246 + nsIWidget* aParentWidget = nullptr, 1.247 + bool aEnableDragDrop = true, 1.248 + bool aResetVisibility = true); 1.249 + 1.250 + /** 1.251 + * Destroys the associated widget for this view. If this method is 1.252 + * not called explicitly, the widget when be destroyed when its 1.253 + * view gets destroyed. 1.254 + */ 1.255 + void DestroyWidget(); 1.256 + 1.257 + /** 1.258 + * Attach/detach a top level widget from this view. When attached, the view 1.259 + * updates the widget's device context and allows the view to begin receiving 1.260 + * gecko events. The underlying base window associated with the widget will 1.261 + * continues to receive events it expects. 1.262 + * 1.263 + * An attached widget will not be destroyed when the view is destroyed, 1.264 + * allowing the recycling of a single top level widget over multiple views. 1.265 + * 1.266 + * @param aWidget The widget to attach to / detach from. 1.267 + */ 1.268 + nsresult AttachToTopLevelWidget(nsIWidget* aWidget); 1.269 + nsresult DetachFromTopLevelWidget(); 1.270 + 1.271 + /** 1.272 + * Returns a flag indicating whether the view owns it's widget 1.273 + * or is attached to an existing top level widget. 1.274 + */ 1.275 + bool IsAttachedToTopLevel() const { return mWidgetIsTopLevel; } 1.276 + 1.277 + /** 1.278 + * In 4.0, the "cutout" nature of a view is queryable. 1.279 + * If we believe that all cutout view have a native widget, this 1.280 + * could be a replacement. 1.281 + * @param aWidget out parameter for widget that this view contains, 1.282 + * or nullptr if there is none. 1.283 + */ 1.284 + nsIWidget* GetWidget() const { return mWindow; } 1.285 + 1.286 + /** 1.287 + * Returns true if the view has a widget associated with it. 1.288 + */ 1.289 + bool HasWidget() const { return mWindow != nullptr; } 1.290 + 1.291 + void SetForcedRepaint(bool aForceRepaint) { 1.292 + mForcedRepaint = aForceRepaint; 1.293 + } 1.294 + 1.295 + /** 1.296 + * Make aWidget direct its events to this view. 1.297 + * The caller must call DetachWidgetEventHandler before this view 1.298 + * is destroyed. 1.299 + */ 1.300 + void AttachWidgetEventHandler(nsIWidget* aWidget); 1.301 + /** 1.302 + * Stop aWidget directing its events to this view. 1.303 + */ 1.304 + void DetachWidgetEventHandler(nsIWidget* aWidget); 1.305 + 1.306 +#ifdef DEBUG 1.307 + /** 1.308 + * Output debug info to FILE 1.309 + * @param out output file handle 1.310 + * @param aIndent indentation depth 1.311 + * NOTE: virtual so that debugging tools not linked into gklayout can access it 1.312 + */ 1.313 + virtual void List(FILE* out, int32_t aIndent = 0) const; 1.314 +#endif // DEBUG 1.315 + 1.316 + /** 1.317 + * @result true iff this is the root view for its view manager 1.318 + */ 1.319 + bool IsRoot() const; 1.320 + 1.321 + nsIntRect CalcWidgetBounds(nsWindowType aType); 1.322 + 1.323 + // This is an app unit offset to add when converting view coordinates to 1.324 + // widget coordinates. It is the offset in view coordinates from widget 1.325 + // origin (unlike views, widgets can't extend above or to the left of their 1.326 + // origin) to view origin expressed in appunits of this. 1.327 + nsPoint ViewToWidgetOffset() const { return mViewToWidgetOffset; } 1.328 + 1.329 + /** 1.330 + * Called to indicate that the position of the view has been changed. 1.331 + * The specified coordinates are in the parent view's coordinate space. 1.332 + * @param x new x position 1.333 + * @param y new y position 1.334 + */ 1.335 + void SetPosition(nscoord aX, nscoord aY); 1.336 + 1.337 + /** 1.338 + * Called to indicate that the z-index of a view has been changed. 1.339 + * The z-index is relative to all siblings of the view. 1.340 + * @param aAuto Indicate that the z-index of a view is "auto". An "auto" z-index 1.341 + * means that the view does not define a new stacking context, 1.342 + * which means that the z-indicies of the view's children are 1.343 + * relative to the view's siblings. 1.344 + * @param zindex new z depth 1.345 + */ 1.346 + void SetZIndex(bool aAuto, int32_t aZIndex); 1.347 + bool GetZIndexIsAuto() const { return (mVFlags & NS_VIEW_FLAG_AUTO_ZINDEX) != 0; } 1.348 + int32_t GetZIndex() const { return mZIndex; } 1.349 + 1.350 + void SetParent(nsView *aParent) { mParent = aParent; } 1.351 + void SetNextSibling(nsView *aSibling) 1.352 + { 1.353 + NS_ASSERTION(aSibling != this, "Can't be our own sibling!"); 1.354 + mNextSibling = aSibling; 1.355 + } 1.356 + 1.357 + nsRegion* GetDirtyRegion() { 1.358 + if (!mDirtyRegion) { 1.359 + NS_ASSERTION(!mParent || GetFloating(), 1.360 + "Only display roots should have dirty regions"); 1.361 + mDirtyRegion = new nsRegion(); 1.362 + NS_ASSERTION(mDirtyRegion, "Out of memory!"); 1.363 + } 1.364 + return mDirtyRegion; 1.365 + } 1.366 + 1.367 + // nsIWidgetListener 1.368 + virtual nsIPresShell* GetPresShell() MOZ_OVERRIDE; 1.369 + virtual nsView* GetView() MOZ_OVERRIDE { return this; } 1.370 + virtual bool WindowMoved(nsIWidget* aWidget, int32_t x, int32_t y) MOZ_OVERRIDE; 1.371 + virtual bool WindowResized(nsIWidget* aWidget, int32_t aWidth, int32_t aHeight) MOZ_OVERRIDE; 1.372 + virtual bool RequestWindowClose(nsIWidget* aWidget) MOZ_OVERRIDE; 1.373 + virtual void WillPaintWindow(nsIWidget* aWidget) MOZ_OVERRIDE; 1.374 + virtual bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion) MOZ_OVERRIDE; 1.375 + virtual void DidPaintWindow() MOZ_OVERRIDE; 1.376 + virtual void DidCompositeWindow() MOZ_OVERRIDE; 1.377 + virtual void RequestRepaint() MOZ_OVERRIDE; 1.378 + virtual nsEventStatus HandleEvent(mozilla::WidgetGUIEvent* aEvent, 1.379 + bool aUseAttachedEvents) MOZ_OVERRIDE; 1.380 + 1.381 + virtual ~nsView(); 1.382 + 1.383 + nsPoint GetOffsetTo(const nsView* aOther, const int32_t aAPD) const; 1.384 + nsIWidget* GetNearestWidget(nsPoint* aOffset, const int32_t aAPD) const; 1.385 + 1.386 +private: 1.387 + nsView(nsViewManager* aViewManager = nullptr, 1.388 + nsViewVisibility aVisibility = nsViewVisibility_kShow); 1.389 + 1.390 + bool ForcedRepaint() { return mForcedRepaint; } 1.391 + 1.392 + // Do the actual work of ResetWidgetBounds, unconditionally. Don't 1.393 + // call this method if we have no widget. 1.394 + void DoResetWidgetBounds(bool aMoveOnly, bool aInvalidateChangedSize); 1.395 + void InitializeWindow(bool aEnableDragDrop, bool aResetVisibility); 1.396 + 1.397 + bool IsEffectivelyVisible(); 1.398 + 1.399 + /** 1.400 + * Called to indicate that the dimensions of the view have been changed. 1.401 + * The x and y coordinates may be < 0, indicating that the view extends above 1.402 + * or to the left of its origin position. The term 'dimensions' indicates it 1.403 + * is relative to this view. 1.404 + */ 1.405 + void SetDimensions(const nsRect &aRect, bool aPaint = true, 1.406 + bool aResizeWidget = true); 1.407 + 1.408 + /** 1.409 + * Called to indicate that the visibility of a view has been 1.410 + * changed. 1.411 + * @param visibility new visibility state 1.412 + */ 1.413 + void SetVisibility(nsViewVisibility visibility); 1.414 + 1.415 + /** 1.416 + * Set/Get whether the view "floats" above all other views, 1.417 + * which tells the compositor not to consider higher views in 1.418 + * the view hierarchy that would geometrically intersect with 1.419 + * this view. This is a hack, but it fixes some problems with 1.420 + * views that need to be drawn in front of all other views. 1.421 + * @result true if the view floats, false otherwise. 1.422 + */ 1.423 + void SetFloating(bool aFloatingView); 1.424 + 1.425 + // Helper function to get mouse grabbing off this view (by moving it to the 1.426 + // parent, if we can) 1.427 + void DropMouseGrabbing(); 1.428 + 1.429 + // Same as GetBounds but converts to parent appunits if they are different. 1.430 + nsRect GetBoundsInParentUnits() const; 1.431 + 1.432 + bool HasNonEmptyDirtyRegion() { 1.433 + return mDirtyRegion && !mDirtyRegion->IsEmpty(); 1.434 + } 1.435 + 1.436 + void InsertChild(nsView *aChild, nsView *aSibling); 1.437 + void RemoveChild(nsView *aChild); 1.438 + 1.439 + void ResetWidgetBounds(bool aRecurse, bool aForceSync); 1.440 + void AssertNoWindow(); 1.441 + 1.442 + void NotifyEffectiveVisibilityChanged(bool aEffectivelyVisible); 1.443 + 1.444 + // Update the cached RootViewManager for all view manager descendents, 1.445 + // If the hierarchy is being removed, aViewManagerParent points to the view 1.446 + // manager for the hierarchy's old parent, and will have its mouse grab 1.447 + // released if it points to any view in this view hierarchy. 1.448 + void InvalidateHierarchy(nsViewManager *aViewManagerParent); 1.449 + 1.450 + nsViewManager *mViewManager; 1.451 + nsView *mParent; 1.452 + nsIWidget *mWindow; 1.453 + nsView *mNextSibling; 1.454 + nsView *mFirstChild; 1.455 + nsIFrame *mFrame; 1.456 + nsRegion *mDirtyRegion; 1.457 + int32_t mZIndex; 1.458 + nsViewVisibility mVis; 1.459 + // position relative our parent view origin but in our appunits 1.460 + nscoord mPosX, mPosY; 1.461 + // relative to parent, but in our appunits 1.462 + nsRect mDimBounds; 1.463 + // in our appunits 1.464 + nsPoint mViewToWidgetOffset; 1.465 + uint32_t mVFlags; 1.466 + bool mWidgetIsTopLevel; 1.467 + bool mForcedRepaint; 1.468 +}; 1.469 + 1.470 +#endif