LCOV - code coverage report
Current view: top level - view - nsView.h (source / functions) Hit Total Coverage
Test: output.info Lines: 33 41 80.5 %
Date: 2017-07-14 16:53:18 Functions: 23 26 88.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #ifndef nsView_h__
       7             : #define nsView_h__
       8             : 
       9             : #include "nsCoord.h"
      10             : #include "nsRect.h"
      11             : #include "nsPoint.h"
      12             : #include "nsRegion.h"
      13             : #include "nsCRT.h"
      14             : #include "nsCOMPtr.h"
      15             : #include "nsWidgetInitData.h" // for nsWindowType
      16             : #include "nsIWidgetListener.h"
      17             : #include "Units.h"
      18             : #include "mozilla/EventForwards.h"
      19             : 
      20             : class nsViewManager;
      21             : class nsIWidget;
      22             : class nsIFrame;
      23             : 
      24             : // Enumerated type to indicate the visibility of a layer.
      25             : // hide - the layer is not shown.
      26             : // show - the layer is shown irrespective of the visibility of
      27             : //        the layer's parent.
      28             : enum nsViewVisibility {
      29             :   nsViewVisibility_kHide = 0,
      30             :   nsViewVisibility_kShow = 1
      31             : };
      32             : 
      33             : // Public view flags
      34             : 
      35             : // Indicates that the view is using auto z-indexing
      36             : #define NS_VIEW_FLAG_AUTO_ZINDEX          0x0004
      37             : 
      38             : // Indicates that the view is a floating view.
      39             : #define NS_VIEW_FLAG_FLOATING             0x0008
      40             : 
      41             : //----------------------------------------------------------------------
      42             : 
      43             : /**
      44             :  * View interface
      45             :  *
      46             :  * Views are NOT reference counted. Use the Destroy() member function to
      47             :  * destroy a view.
      48             :  *
      49             :  * The lifetime of the view hierarchy is bounded by the lifetime of the
      50             :  * view manager that owns the views.
      51             :  *
      52             :  * Most of the methods here are read-only. To set the corresponding properties
      53             :  * of a view, go through nsViewManager.
      54             :  */
      55             : 
      56             : class nsView final : public nsIWidgetListener
      57             : {
      58             : public:
      59             :   friend class nsViewManager;
      60             : 
      61             :   typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect;
      62             :   typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion;
      63             : 
      64          15 :   void operator delete(void* ptr) {
      65             :     ::operator delete(ptr);
      66          15 :   }
      67             : 
      68             :   /**
      69             :    * Get the view manager which "owns" the view.
      70             :    * This method might require some expensive traversal work in the future. If you can get the
      71             :    * view manager from somewhere else, do that instead.
      72             :    * @result the view manager
      73             :    */
      74        5365 :   nsViewManager* GetViewManager() const { return mViewManager; }
      75             : 
      76             :   /**
      77             :    * Find the view for the given widget, if there is one.
      78             :    * @return the view the widget belongs to, or null if the widget doesn't
      79             :    * belong to any view.
      80             :    */
      81             :   static nsView* GetViewFor(nsIWidget* aWidget);
      82             : 
      83             :   /**
      84             :    * Destroy the view.
      85             :    *
      86             :    * The view destroys its child views, and destroys and releases its
      87             :    * widget (if it has one).
      88             :    *
      89             :    * Also informs the view manager that the view is destroyed by calling
      90             :    * SetRootView(NULL) if the view is the root view and calling RemoveChild()
      91             :    * otherwise.
      92             :    */
      93             :   void Destroy();
      94             : 
      95             :   /**
      96             :    * Called to get the position of a view.
      97             :    * The specified coordinates are relative to the parent view's origin, but
      98             :    * are in appunits of this.
      99             :    * This is the (0, 0) origin of the coordinate space established by this view.
     100             :    * @param x out parameter for x position
     101             :    * @param y out parameter for y position
     102             :    */
     103          40 :   nsPoint GetPosition() const {
     104          40 :     NS_ASSERTION(!IsRoot() || (mPosX == 0 && mPosY == 0),
     105             :                  "root views should always have explicit position of (0,0)");
     106          40 :     return nsPoint(mPosX, mPosY);
     107             :   }
     108             : 
     109             :   /**
     110             :    * Called to get the dimensions and position of the view's bounds.
     111             :    * The view's bounds (x,y) are relative to the origin of the parent view, but
     112             :    * are in appunits of this.
     113             :    * The view's bounds (x,y) might not be the same as the view's position,
     114             :    * if the view has content above or to the left of its origin.
     115             :    * @param aBounds out parameter for bounds
     116             :    */
     117          33 :   nsRect GetBounds() const { return mDimBounds; }
     118             : 
     119             :   /**
     120             :    * The bounds of this view relative to this view. So this is the same as
     121             :    * GetBounds except this is relative to this view instead of the parent view.
     122             :    */
     123         136 :   nsRect GetDimensions() const {
     124         136 :     nsRect r = mDimBounds; r.MoveBy(-mPosX, -mPosY); return r;
     125             :   }
     126             : 
     127             :   /**
     128             :    * Get the offset between the coordinate systems of |this| and aOther.
     129             :    * Adding the return value to a point in the coordinate system of |this|
     130             :    * will transform the point to the coordinate system of aOther.
     131             :    *
     132             :    * The offset is expressed in appunits of |this|. So if you are getting the
     133             :    * offset between views in different documents that might have different
     134             :    * appunits per devpixel ratios you need to be careful how you use the
     135             :    * result.
     136             :    *
     137             :    * If aOther is null, this will return the offset of |this| from the
     138             :    * root of the viewmanager tree.
     139             :    *
     140             :    * This function is fastest when aOther is an ancestor of |this|.
     141             :    *
     142             :    * NOTE: this actually returns the offset from aOther to |this|, but
     143             :    * that offset is added to transform _coordinates_ from |this| to aOther.
     144             :    */
     145             :   nsPoint GetOffsetTo(const nsView* aOther) const;
     146             : 
     147             :   /**
     148             :    * Get the offset between the origin of |this| and the origin of aWidget.
     149             :    * Adding the return value to a point in the coordinate system of |this|
     150             :    * will transform the point to the coordinate system of aWidget.
     151             :    *
     152             :    * The offset is expressed in appunits of |this|.
     153             :    */
     154             :   nsPoint GetOffsetToWidget(nsIWidget* aWidget) const;
     155             : 
     156             :   /**
     157             :    * Takes a point aPt that is in the coordinate system of |this|'s parent view
     158             :    * and converts it to be in the coordinate system of |this| taking into
     159             :    * account the offset and any app unit per dev pixel ratio differences.
     160             :    */
     161             :   nsPoint ConvertFromParentCoords(nsPoint aPt) const;
     162             : 
     163             :   /**
     164             :    * Called to query the visibility state of a view.
     165             :    * @result current visibility state
     166             :    */
     167         112 :   nsViewVisibility GetVisibility() const { return mVis; }
     168             : 
     169             :   /**
     170             :    * Get whether the view "floats" above all other views,
     171             :    * which tells the compositor not to consider higher views in
     172             :    * the view hierarchy that would geometrically intersect with
     173             :    * this view. This is a hack, but it fixes some problems with
     174             :    * views that need to be drawn in front of all other views.
     175             :    * @result true if the view floats, false otherwise.
     176             :    */
     177          50 :   bool GetFloating() const { return (mVFlags & NS_VIEW_FLAG_FLOATING) != 0; }
     178             : 
     179             :   /**
     180             :    * Called to query the parent of the view.
     181             :    * @result view's parent
     182             :    */
     183       20198 :   nsView* GetParent() const { return mParent; }
     184             : 
     185             :   /**
     186             :    * The view's first child is the child which is earliest in document order.
     187             :    * @result first child
     188             :    */
     189        1824 :   nsView* GetFirstChild() const { return mFirstChild; }
     190             : 
     191             :   /**
     192             :    * Called to query the next sibling of the view.
     193             :    * @result view's next sibling
     194             :    */
     195        2515 :   nsView* GetNextSibling() const { return mNextSibling; }
     196             : 
     197             :   /**
     198             :    * Set the view's frame.
     199             :    */
     200          89 :   void SetFrame(nsIFrame* aRootFrame) { mFrame = aRootFrame; }
     201             : 
     202             :   /**
     203             :    * Retrieve the view's frame.
     204             :    */
     205          84 :   nsIFrame* GetFrame() const { return mFrame; }
     206             : 
     207             :   /**
     208             :    * Get the nearest widget in this view or a parent of this view and
     209             :    * the offset from the widget's origin to this view's origin
     210             :    * @param aOffset - if non-null the offset from this view's origin to the
     211             :    * widget's origin (usually positive) expressed in appunits of this will be
     212             :    * returned in aOffset.
     213             :    * @return the widget closest to this view; can be null because some view trees
     214             :    * don't have widgets at all (e.g., printing), but if any view in the view tree
     215             :    * has a widget, then it's safe to assume this will not return null
     216             :    */
     217             :   nsIWidget* GetNearestWidget(nsPoint* aOffset) const;
     218             : 
     219             :   /**
     220             :    * Create a widget to associate with this view.  This variant of
     221             :    * CreateWidget*() will look around in the view hierarchy for an
     222             :    * appropriate parent widget for the view.
     223             :    *
     224             :    * @param aWidgetInitData data used to initialize this view's widget before
     225             :    *        its create is called.
     226             :    * @return error status
     227             :    */
     228             :   nsresult CreateWidget(nsWidgetInitData *aWidgetInitData = nullptr,
     229             :                         bool aEnableDragDrop = true,
     230             :                         bool aResetVisibility = true);
     231             : 
     232             :   /**
     233             :    * Create a widget for this view with an explicit parent widget.
     234             :    * |aParentWidget| must be nonnull.  The other params are the same
     235             :    * as for |CreateWidget()|.
     236             :    */
     237             :   nsresult CreateWidgetForParent(nsIWidget* aParentWidget,
     238             :                                  nsWidgetInitData *aWidgetInitData = nullptr,
     239             :                                  bool aEnableDragDrop = true,
     240             :                                  bool aResetVisibility = true);
     241             : 
     242             :   /**
     243             :    * Create a popup widget for this view.  Pass |aParentWidget| to
     244             :    * explicitly set the popup's parent.  If it's not passed, the view
     245             :    * hierarchy will be searched for an appropriate parent widget.  The
     246             :    * other params are the same as for |CreateWidget()|, except that
     247             :    * |aWidgetInitData| must be nonnull.
     248             :    */
     249             :   nsresult CreateWidgetForPopup(nsWidgetInitData *aWidgetInitData,
     250             :                                 nsIWidget* aParentWidget = nullptr,
     251             :                                 bool aEnableDragDrop = true,
     252             :                                 bool aResetVisibility = true);
     253             : 
     254             :   /**
     255             :    * Destroys the associated widget for this view.  If this method is
     256             :    * not called explicitly, the widget when be destroyed when its
     257             :    * view gets destroyed.
     258             :    */
     259             :   void DestroyWidget();
     260             : 
     261             :   /**
     262             :    * Attach/detach a top level widget from this view. When attached, the view
     263             :    * updates the widget's device context and allows the view to begin receiving
     264             :    * gecko events. The underlying base window associated with the widget will
     265             :    * continues to receive events it expects.
     266             :    *
     267             :    * An attached widget will not be destroyed when the view is destroyed,
     268             :    * allowing the recycling of a single top level widget over multiple views.
     269             :    *
     270             :    * @param aWidget The widget to attach to / detach from.
     271             :    */
     272             :   nsresult AttachToTopLevelWidget(nsIWidget* aWidget);
     273             :   nsresult DetachFromTopLevelWidget();
     274             : 
     275             :   /**
     276             :    * Returns a flag indicating whether the view owns it's widget
     277             :    * or is attached to an existing top level widget.
     278             :    */
     279           0 :   bool IsAttachedToTopLevel() const { return mWidgetIsTopLevel; }
     280             : 
     281             :   /**
     282             :    * In 4.0, the "cutout" nature of a view is queryable.
     283             :    * If we believe that all cutout view have a native widget, this
     284             :    * could be a replacement.
     285             :    * @param aWidget out parameter for widget that this view contains,
     286             :    *        or nullptr if there is none.
     287             :    */
     288        2864 :   nsIWidget* GetWidget() const { return mWindow; }
     289             : 
     290             :   /**
     291             :    * The widget which we have attached a listener to can also have a "previous"
     292             :    * listener set on it. This is to keep track of the last nsView when navigating
     293             :    * to a new one so that we can continue to paint that if the new one isn't ready
     294             :    * yet.
     295             :    */
     296           0 :   void SetPreviousWidget(nsIWidget* aWidget) { mPreviousWindow = aWidget; }
     297             : 
     298             :   /**
     299             :    * Returns true if the view has a widget associated with it.
     300             :    */
     301        1528 :   bool HasWidget() const { return mWindow != nullptr; }
     302             : 
     303          36 :   void SetForcedRepaint(bool aForceRepaint) {
     304          36 :     mForcedRepaint = aForceRepaint;
     305          36 :   }
     306             : 
     307             :   void SetNeedsWindowPropertiesSync();
     308             : 
     309             :   /**
     310             :    * Make aWidget direct its events to this view.
     311             :    * The caller must call DetachWidgetEventHandler before this view
     312             :    * is destroyed.
     313             :    */
     314             :   void AttachWidgetEventHandler(nsIWidget* aWidget);
     315             :   /**
     316             :    * Stop aWidget directing its events to this view.
     317             :    */
     318             :   void DetachWidgetEventHandler(nsIWidget* aWidget);
     319             : 
     320             : #ifdef DEBUG
     321             :   /**
     322             :    * Output debug info to FILE
     323             :    * @param out output file handle
     324             :    * @param aIndent indentation depth
     325             :    * NOTE: virtual so that debugging tools not linked into gklayout can access it
     326             :    */
     327             :   virtual void List(FILE* out, int32_t aIndent = 0) const;
     328             : #endif // DEBUG
     329             : 
     330             :   /**
     331             :    * @result true iff this is the root view for its view manager
     332             :    */
     333             :   bool IsRoot() const;
     334             : 
     335             :   LayoutDeviceIntRect CalcWidgetBounds(nsWindowType aType);
     336             : 
     337             :   // This is an app unit offset to add when converting view coordinates to
     338             :   // widget coordinates.  It is the offset in view coordinates from widget
     339             :   // origin (unlike views, widgets can't extend above or to the left of their
     340             :   // origin) to view origin expressed in appunits of this.
     341          51 :   nsPoint ViewToWidgetOffset() const { return mViewToWidgetOffset; }
     342             : 
     343             :   /**
     344             :    * Called to indicate that the position of the view has been changed.
     345             :    * The specified coordinates are in the parent view's coordinate space.
     346             :    * @param x new x position
     347             :    * @param y new y position
     348             :    */
     349             :   void SetPosition(nscoord aX, nscoord aY);
     350             : 
     351             :   /**
     352             :    * Called to indicate that the z-index of a view has been changed.
     353             :    * The z-index is relative to all siblings of the view.
     354             :    * @param aAuto Indicate that the z-index of a view is "auto". An "auto" z-index
     355             :    * means that the view does not define a new stacking context,
     356             :    * which means that the z-indicies of the view's children are
     357             :    * relative to the view's siblings.
     358             :    * @param zindex new z depth
     359             :    */
     360             :   void SetZIndex(bool aAuto, int32_t aZIndex);
     361         165 :   bool GetZIndexIsAuto() const { return (mVFlags & NS_VIEW_FLAG_AUTO_ZINDEX) != 0; }
     362          78 :   int32_t GetZIndex() const { return mZIndex; }
     363             : 
     364         141 :   void SetParent(nsView *aParent) { mParent = aParent; }
     365          61 :   void SetNextSibling(nsView *aSibling)
     366             :   {
     367          61 :     NS_ASSERTION(aSibling != this, "Can't be our own sibling!");
     368          61 :     mNextSibling = aSibling;
     369          61 :   }
     370             : 
     371           0 :   nsRegion* GetDirtyRegion() {
     372           0 :     if (!mDirtyRegion) {
     373           0 :       NS_ASSERTION(!mParent || GetFloating(),
     374             :                    "Only display roots should have dirty regions");
     375           0 :       mDirtyRegion = new nsRegion();
     376           0 :       NS_ASSERTION(mDirtyRegion, "Out of memory!");
     377             :     }
     378           0 :     return mDirtyRegion;
     379             :   }
     380             : 
     381             :   // nsIWidgetListener
     382             :   virtual nsIPresShell* GetPresShell() override;
     383         209 :   virtual nsView* GetView() override { return this; }
     384             :   virtual bool WindowMoved(nsIWidget* aWidget, int32_t x, int32_t y) override;
     385             :   virtual bool WindowResized(nsIWidget* aWidget, int32_t aWidth, int32_t aHeight) override;
     386             :   virtual bool RequestWindowClose(nsIWidget* aWidget) override;
     387             :   virtual void WillPaintWindow(nsIWidget* aWidget) override;
     388             :   virtual bool PaintWindow(nsIWidget* aWidget,
     389             :                            LayoutDeviceIntRegion aRegion) override;
     390             :   virtual void DidPaintWindow() override;
     391             :   virtual void DidCompositeWindow(uint64_t aTransactionId,
     392             :                                   const mozilla::TimeStamp& aCompositeStart,
     393             :                                   const mozilla::TimeStamp& aCompositeEnd) override;
     394             :   virtual void RequestRepaint() override;
     395             :   virtual nsEventStatus HandleEvent(mozilla::WidgetGUIEvent* aEvent,
     396             :                                     bool aUseAttachedEvents) override;
     397             : 
     398             :   virtual ~nsView();
     399             : 
     400             :   nsPoint GetOffsetTo(const nsView* aOther, const int32_t aAPD) const;
     401             :   nsIWidget* GetNearestWidget(nsPoint* aOffset, const int32_t aAPD) const;
     402             : 
     403             :   bool IsPrimaryFramePaintSuppressed();
     404             : 
     405             : private:
     406             :   explicit nsView(nsViewManager* aViewManager = nullptr,
     407             :                   nsViewVisibility aVisibility = nsViewVisibility_kShow);
     408             : 
     409           3 :   bool ForcedRepaint() { return mForcedRepaint; }
     410             : 
     411             :   // Do the actual work of ResetWidgetBounds, unconditionally.  Don't
     412             :   // call this method if we have no widget.
     413             :   void DoResetWidgetBounds(bool aMoveOnly, bool aInvalidateChangedSize);
     414             :   void InitializeWindow(bool aEnableDragDrop, bool aResetVisibility);
     415             : 
     416             :   bool IsEffectivelyVisible();
     417             : 
     418             :   /**
     419             :    * Called to indicate that the dimensions of the view have been changed.
     420             :    * The x and y coordinates may be < 0, indicating that the view extends above
     421             :    * or to the left of its origin position. The term 'dimensions' indicates it
     422             :    * is relative to this view.
     423             :    */
     424             :   void SetDimensions(const nsRect &aRect, bool aPaint = true,
     425             :                      bool aResizeWidget = true);
     426             : 
     427             :   /**
     428             :    * Called to indicate that the visibility of a view has been
     429             :    * changed.
     430             :    * @param visibility new visibility state
     431             :    */
     432             :   void SetVisibility(nsViewVisibility visibility);
     433             : 
     434             :   /**
     435             :    * Set/Get whether the view "floats" above all other views,
     436             :    * which tells the compositor not to consider higher views in
     437             :    * the view hierarchy that would geometrically intersect with
     438             :    * this view. This is a hack, but it fixes some problems with
     439             :    * views that need to be drawn in front of all other views.
     440             :    * @result true if the view floats, false otherwise.
     441             :    */
     442             :   void SetFloating(bool aFloatingView);
     443             : 
     444             :   // Helper function to get mouse grabbing off this view (by moving it to the
     445             :   // parent, if we can)
     446             :   void DropMouseGrabbing();
     447             : 
     448             :   // Same as GetBounds but converts to parent appunits if they are different.
     449             :   nsRect GetBoundsInParentUnits() const;
     450             : 
     451        1456 :   bool HasNonEmptyDirtyRegion() {
     452        1456 :     return mDirtyRegion && !mDirtyRegion->IsEmpty();
     453             :   }
     454             : 
     455             :   void InsertChild(nsView *aChild, nsView *aSibling);
     456             :   void RemoveChild(nsView *aChild);
     457             : 
     458             :   void ResetWidgetBounds(bool aRecurse, bool aForceSync);
     459             :   void AssertNoWindow();
     460             : 
     461             :   void NotifyEffectiveVisibilityChanged(bool aEffectivelyVisible);
     462             : 
     463             :   // Update the cached RootViewManager for all view manager descendents.
     464             :   void InvalidateHierarchy();
     465             : 
     466             :   nsViewManager    *mViewManager;
     467             :   nsView           *mParent;
     468             :   nsCOMPtr<nsIWidget> mWindow;
     469             :   nsCOMPtr<nsIWidget> mPreviousWindow;
     470             :   nsView           *mNextSibling;
     471             :   nsView           *mFirstChild;
     472             :   nsIFrame         *mFrame;
     473             :   nsRegion         *mDirtyRegion;
     474             :   int32_t           mZIndex;
     475             :   nsViewVisibility  mVis;
     476             :   // position relative our parent view origin but in our appunits
     477             :   nscoord           mPosX, mPosY;
     478             :   // relative to parent, but in our appunits
     479             :   nsRect            mDimBounds;
     480             :   // in our appunits
     481             :   nsPoint           mViewToWidgetOffset;
     482             :   uint32_t          mVFlags;
     483             :   bool              mWidgetIsTopLevel;
     484             :   bool              mForcedRepaint;
     485             :   bool              mNeedsWindowPropertiesSync;
     486             : };
     487             : 
     488             : #endif

Generated by: LCOV version 1.13