view/public/nsView.h

changeset 0
6474c204b198
     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

mercurial