view/public/nsViewManager.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/view/public/nsViewManager.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,442 @@
     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 nsViewManager_h___
    1.10 +#define nsViewManager_h___
    1.11 +
    1.12 +#include "nscore.h"
    1.13 +#include "nsView.h"
    1.14 +#include "nsCOMPtr.h"
    1.15 +#include "nsCRT.h"
    1.16 +#include "nsVoidArray.h"
    1.17 +#include "nsDeviceContext.h"
    1.18 +#include "nsTArray.h"
    1.19 +#include "mozilla/EventForwards.h"
    1.20 +
    1.21 +class nsIWidget;
    1.22 +struct nsRect;
    1.23 +class nsRegion;
    1.24 +class nsDeviceContext;
    1.25 +class nsIPresShell;
    1.26 +
    1.27 +class nsViewManager MOZ_FINAL
    1.28 +{
    1.29 +public:
    1.30 +  friend class nsView;
    1.31 +
    1.32 +  NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
    1.33 +
    1.34 +  NS_INLINE_DECL_REFCOUNTING(nsViewManager)
    1.35 +
    1.36 +  nsViewManager();
    1.37 +  ~nsViewManager();
    1.38 +
    1.39 +  /**
    1.40 +   * Initialize the ViewManager
    1.41 +   * Note: this instance does not hold a reference to the presshell
    1.42 +   * because it holds a reference to this instance.
    1.43 +   * @result The result of the initialization, NS_OK if no errors
    1.44 +   */
    1.45 +  nsresult Init(nsDeviceContext* aContext);
    1.46 +
    1.47 +  /**
    1.48 +   * Create an ordinary view
    1.49 +   * @param aBounds initial bounds for view
    1.50 +   *        XXX We should eliminate this parameter; you can set the bounds after CreateView
    1.51 +   * @param aParent intended parent for view. this is not actually set in the
    1.52 +   *        nsView through this method. it is only used by the initialization
    1.53 +   *        code to walk up the view tree, if necessary, to find resources.
    1.54 +   *        XXX We should eliminate this parameter!
    1.55 +   * @param aVisibilityFlag initial visibility state of view
    1.56 +   *        XXX We should eliminate this parameter; you can set it after CreateView
    1.57 +   * @result The new view.  Never null.
    1.58 +   */
    1.59 +  nsView* CreateView(const nsRect& aBounds,
    1.60 +                     nsView* aParent,
    1.61 +                     nsViewVisibility aVisibilityFlag = nsViewVisibility_kShow);
    1.62 +
    1.63 +  /**
    1.64 +   * Get the root of the view tree.
    1.65 +   * @result the root view
    1.66 +   */
    1.67 +  nsView* GetRootView() { return mRootView; }
    1.68 +
    1.69 +  /**
    1.70 +   * Set the root of the view tree. Does not destroy the current root view.
    1.71 +   * aView may have a parent view managed by a different view manager.
    1.72 +   * aView may have a widget (anything but printing) or may not (printing).
    1.73 +   * @param aView view to set as root
    1.74 +   */
    1.75 +  void SetRootView(nsView *aView);
    1.76 +
    1.77 +  /**
    1.78 +   * Get the dimensions of the root window. The dimensions are in
    1.79 +   * twips
    1.80 +   * @param aWidth out parameter for width of window in twips
    1.81 +   * @param aHeight out parameter for height of window in twips
    1.82 +   */
    1.83 +  void GetWindowDimensions(nscoord *aWidth, nscoord *aHeight);
    1.84 +
    1.85 +  /**
    1.86 +   * Set the dimensions of the root window.
    1.87 +   * Called if the root window is resized. The dimensions are in
    1.88 +   * twips
    1.89 +   * @param aWidth of window in twips
    1.90 +   * @param aHeight of window in twips
    1.91 +   */
    1.92 +  void SetWindowDimensions(nscoord aWidth, nscoord aHeight);
    1.93 +
    1.94 +  /**
    1.95 +   * Do any resizes that are pending.
    1.96 +   */
    1.97 +  void FlushDelayedResize(bool aDoReflow);
    1.98 +
    1.99 +  /**
   1.100 +   * Called to inform the view manager that the entire area of a view
   1.101 +   * is dirty and needs to be redrawn.
   1.102 +   * @param aView view to paint. should be root view
   1.103 +   */
   1.104 +  void InvalidateView(nsView *aView);
   1.105 +
   1.106 +  /**
   1.107 +   * Called to inform the view manager that some portion of a view is dirty and
   1.108 +   * needs to be redrawn. The rect passed in should be in the view's coordinate
   1.109 +   * space. Does not check for paint suppression.
   1.110 +   * @param aView view to paint. should be root view
   1.111 +   * @param rect rect to mark as damaged
   1.112 +   */
   1.113 +  void InvalidateViewNoSuppression(nsView *aView, const nsRect &aRect);
   1.114 +
   1.115 +  /**
   1.116 +   * Called to inform the view manager that it should invalidate all views.
   1.117 +   */
   1.118 +  void InvalidateAllViews();
   1.119 +
   1.120 +  /**
   1.121 +   * Called to dispatch an event to the appropriate view. Often called
   1.122 +   * as a result of receiving a mouse or keyboard event from the widget
   1.123 +   * event system.
   1.124 +   * @param aEvent event to dispatch
   1.125 +   * @param aViewTarget dispatch the event to this view
   1.126 +   * @param aStatus event handling status
   1.127 +   */
   1.128 +  void DispatchEvent(mozilla::WidgetGUIEvent *aEvent,
   1.129 +                     nsView* aViewTarget,
   1.130 +                     nsEventStatus* aStatus);
   1.131 +
   1.132 +  /**
   1.133 +   * Given a parent view, insert another view as its child.
   1.134 +   * aSibling and aAbove control the "document order" for the insertion.
   1.135 +   * If aSibling is null, the view is inserted at the end of the document order
   1.136 +   * if aAfter is true, otherwise it is inserted at the beginning.
   1.137 +   * If aSibling is non-null, then if aAfter is true, the view is inserted
   1.138 +   * after the sibling in document order (appearing above the sibling unless
   1.139 +   * overriden by z-order).
   1.140 +   * If it is false, the view is inserted before the sibling.
   1.141 +   * The view manager generates the appopriate dirty regions.
   1.142 +   * @param aParent parent view
   1.143 +   * @param aChild child view
   1.144 +   * @param aSibling sibling view
   1.145 +   * @param aAfter after or before in the document order
   1.146 +   */
   1.147 +  void InsertChild(nsView *aParent, nsView *aChild, nsView *aSibling,
   1.148 +                   bool aAfter);
   1.149 +
   1.150 +  void InsertChild(nsView *aParent, nsView *aChild, int32_t aZIndex);
   1.151 +
   1.152 +  /**
   1.153 +   * Remove a specific child view from its parent. This will NOT remove its placeholder
   1.154 +   * if there is one.
   1.155 +   * The view manager generates the appropriate dirty regions.
   1.156 +   * @param aParent parent view
   1.157 +   * @param aChild child view
   1.158 +   */
   1.159 +  void RemoveChild(nsView *aChild);
   1.160 +
   1.161 +  /**
   1.162 +   * Move a view to the specified position, provided in parent coordinates.
   1.163 +   * The new position is the (0, 0) origin for the view's coordinate system.
   1.164 +   * The view's bounds may extend above or to the left of this point.
   1.165 +   * The view manager generates the appropriate dirty regions.
   1.166 +   * @param aView view to move
   1.167 +   * @param aX x value for new view position
   1.168 +   * @param aY y value for new view position
   1.169 +   */
   1.170 +  void MoveViewTo(nsView *aView, nscoord aX, nscoord aY);
   1.171 +
   1.172 +  /**
   1.173 +   * Resize a view. In addition to setting the width and height, you can
   1.174 +   * set the x and y of its bounds relative to its position. Negative x and y
   1.175 +   * will let the view extend above and to the left of the (0,0) point in its
   1.176 +   * coordinate system.
   1.177 +   * The view manager generates the appropriate dirty regions.
   1.178 +   * @param aView view to move
   1.179 +   * @param the new bounds relative to the current position
   1.180 +   * @param RepaintExposedAreaOnly
   1.181 +   *     if true Repaint only the expanded or contracted region,
   1.182 +   *     if false Repaint the union of the old and new rectangles.
   1.183 +   */
   1.184 +  void ResizeView(nsView *aView, const nsRect &aRect,
   1.185 +                  bool aRepaintExposedAreaOnly = false);
   1.186 +
   1.187 +  /**
   1.188 +   * Set the visibility of a view. Hidden views have the effect of hiding
   1.189 +   * their descendants as well. This does not affect painting, so layout
   1.190 +   * is responsible for ensuring that content in hidden views is not
   1.191 +   * painted nor handling events. It does affect the visibility of widgets;
   1.192 +   * if a view is hidden, descendant views with widgets have their widgets
   1.193 +   * hidden.
   1.194 +   * The view manager generates the appropriate dirty regions.
   1.195 +   * @param aView view to change visibility state of
   1.196 +   * @param visible new visibility state
   1.197 +   */
   1.198 +  void SetViewVisibility(nsView *aView, nsViewVisibility aVisible);
   1.199 +
   1.200 +  /**
   1.201 +   * Set the z-index of a view. Positive z-indices mean that a view
   1.202 +   * is above its parent in z-order. Negative z-indices mean that a
   1.203 +   * view is below its parent.
   1.204 +   * The view manager generates the appropriate dirty regions.
   1.205 +   * @param aAutoZIndex indicate that the z-index of a view is "auto". An "auto" z-index
   1.206 +   * means that the view does not define a new stacking context,
   1.207 +   * which means that the z-indicies of the view's children are
   1.208 +   * relative to the view's siblings.
   1.209 +   * @param aView view to change z depth of
   1.210 +   * @param aZindex explicit z depth
   1.211 +   */
   1.212 +  void SetViewZIndex(nsView *aView, bool aAutoZIndex, int32_t aZindex);
   1.213 +
   1.214 +  /**
   1.215 +   * Set whether the view "floats" above all other views,
   1.216 +   * which tells the compositor not to consider higher views in
   1.217 +   * the view hierarchy that would geometrically intersect with
   1.218 +   * this view. This is a hack, but it fixes some problems with
   1.219 +   * views that need to be drawn in front of all other views.
   1.220 +   */
   1.221 +  void SetViewFloating(nsView *aView, bool aFloatingView);
   1.222 +
   1.223 +  /**
   1.224 +   * Set the presshell associated with this manager
   1.225 +   * @param aPresShell - new presshell
   1.226 +   */
   1.227 +  void SetPresShell(nsIPresShell *aPresShell) { mPresShell = aPresShell; }
   1.228 +
   1.229 +  /**
   1.230 +   * Get the pres shell associated with this manager
   1.231 +   */
   1.232 +  nsIPresShell* GetPresShell() { return mPresShell; }
   1.233 +
   1.234 +  /**
   1.235 +   * Get the device context associated with this manager
   1.236 +   */
   1.237 +  nsDeviceContext* GetDeviceContext() const
   1.238 +  {
   1.239 +    return mContext;
   1.240 +  }
   1.241 +
   1.242 +  /**
   1.243 +   * A stack class for disallowing changes that would enter painting. For
   1.244 +   * example, popup widgets shouldn't be resized during reflow, since doing so
   1.245 +   * might cause synchronous painting inside reflow which is forbidden.
   1.246 +   * While refresh is disabled, widget geometry changes are deferred and will
   1.247 +   * be handled later, either from the refresh driver or from an NS_WILL_PAINT
   1.248 +   * event.
   1.249 +   * We don't want to defer widget geometry changes all the time. Resizing a
   1.250 +   * popup from script doesn't need to be deferred, for example, especially
   1.251 +   * since popup widget geometry is observable from script and expected to
   1.252 +   * update synchronously.
   1.253 +   */
   1.254 +  class MOZ_STACK_CLASS AutoDisableRefresh {
   1.255 +  public:
   1.256 +    AutoDisableRefresh(nsViewManager* aVM) {
   1.257 +      if (aVM) {
   1.258 +        mRootVM = aVM->IncrementDisableRefreshCount();
   1.259 +      }
   1.260 +    }
   1.261 +    ~AutoDisableRefresh() {
   1.262 +      if (mRootVM) {
   1.263 +        mRootVM->DecrementDisableRefreshCount();
   1.264 +      }
   1.265 +    }
   1.266 +  private:
   1.267 +    AutoDisableRefresh(const AutoDisableRefresh& aOther);
   1.268 +    const AutoDisableRefresh& operator=(const AutoDisableRefresh& aOther);
   1.269 +
   1.270 +    nsRefPtr<nsViewManager> mRootVM;
   1.271 +  };
   1.272 +
   1.273 +private:
   1.274 +  friend class AutoDisableRefresh;
   1.275 +
   1.276 +  nsViewManager* IncrementDisableRefreshCount();
   1.277 +  void DecrementDisableRefreshCount();
   1.278 +
   1.279 +public:
   1.280 +  /**
   1.281 +   * Retrieve the widget at the root of the nearest enclosing
   1.282 +   * view manager whose root view has a widget.
   1.283 +   */
   1.284 +  void GetRootWidget(nsIWidget **aWidget);
   1.285 +
   1.286 +  /**
   1.287 +   * Indicate whether the viewmanager is currently painting
   1.288 +   *
   1.289 +   * @param aPainting true if the viewmanager is painting
   1.290 +   *                  false otherwise
   1.291 +   */
   1.292 +  void IsPainting(bool& aIsPainting);
   1.293 +
   1.294 +  /**
   1.295 +   * Retrieve the time of the last user event. User events
   1.296 +   * include mouse and keyboard events. The viewmanager
   1.297 +   * saves the time of the last user event.
   1.298 +   *
   1.299 +   * @param aTime Last user event time in microseconds
   1.300 +   */
   1.301 +  void GetLastUserEventTime(uint32_t& aTime);
   1.302 +
   1.303 +  /**
   1.304 +   * Find the nearest display root view for the view aView. This is the view for
   1.305 +   * the nearest enclosing popup or the root view for the root document.
   1.306 +   */
   1.307 +  static nsView* GetDisplayRootFor(nsView* aView);
   1.308 +
   1.309 +  /**
   1.310 +   * Flush the accumulated dirty region to the widget and update widget
   1.311 +   * geometry.
   1.312 +   */
   1.313 +  void ProcessPendingUpdates();
   1.314 +
   1.315 +  /**
   1.316 +   * Just update widget geometry without flushing the dirty region
   1.317 +   */
   1.318 +  void UpdateWidgetGeometry();
   1.319 +
   1.320 +  int32_t AppUnitsPerDevPixel() const
   1.321 +  {
   1.322 +    return mContext->AppUnitsPerDevPixel();
   1.323 +  }
   1.324 +
   1.325 +private:
   1.326 +  static uint32_t gLastUserEventTime;
   1.327 +
   1.328 +  /* Update the cached RootViewManager pointer on this view manager. */
   1.329 +  void InvalidateHierarchy();
   1.330 +  void FlushPendingInvalidates();
   1.331 +
   1.332 +  void ProcessPendingUpdatesForView(nsView *aView,
   1.333 +                                    bool aFlushDirtyRegion = true);
   1.334 +  void ProcessPendingUpdatesRecurse(nsView* aView,
   1.335 +                                    nsTArray<nsCOMPtr<nsIWidget> >& aWidgets);
   1.336 +  void ProcessPendingUpdatesPaint(nsIWidget* aWidget);
   1.337 +
   1.338 +  void FlushDirtyRegionToWidget(nsView* aView);
   1.339 +  /**
   1.340 +   * Call WillPaint() on all view observers under this vm root.
   1.341 +   */
   1.342 +  void CallWillPaintOnObservers();
   1.343 +  void ReparentChildWidgets(nsView* aView, nsIWidget *aNewWidget);
   1.344 +  void ReparentWidgets(nsView* aView, nsView *aParent);
   1.345 +  void InvalidateWidgetArea(nsView *aWidgetView, const nsRegion &aDamagedRegion);
   1.346 +
   1.347 +  void InvalidateViews(nsView *aView);
   1.348 +
   1.349 +  // aView is the view for aWidget and aRegion is relative to aWidget.
   1.350 +  void Refresh(nsView *aView, const nsIntRegion& aRegion);
   1.351 +
   1.352 +  // Utilities
   1.353 +
   1.354 +  bool IsViewInserted(nsView *aView);
   1.355 +
   1.356 +  /**
   1.357 +   * Intersects aRect with aView's bounds and then transforms it from aView's
   1.358 +   * coordinate system to the coordinate system of the widget attached to
   1.359 +   * aView.
   1.360 +   */
   1.361 +  nsIntRect ViewToWidget(nsView *aView, const nsRect &aRect) const;
   1.362 +
   1.363 +  void DoSetWindowDimensions(nscoord aWidth, nscoord aHeight);
   1.364 +
   1.365 +  bool IsPainting() const {
   1.366 +    return RootViewManager()->mPainting;
   1.367 +  }
   1.368 +
   1.369 +  void SetPainting(bool aPainting) {
   1.370 +    RootViewManager()->mPainting = aPainting;
   1.371 +  }
   1.372 +
   1.373 +  void InvalidateView(nsView *aView, const nsRect &aRect);
   1.374 +
   1.375 +  nsViewManager* RootViewManager() const { return mRootViewManager; }
   1.376 +  bool IsRootVM() const { return this == RootViewManager(); }
   1.377 +
   1.378 +  // Whether synchronous painting is allowed at the moment. For example,
   1.379 +  // widget geometry changes can cause synchronous painting, so they need to
   1.380 +  // be deferred while refresh is disabled.
   1.381 +  bool IsPaintingAllowed() { return RootViewManager()->mRefreshDisableCount == 0; }
   1.382 +
   1.383 +  void WillPaintWindow(nsIWidget* aWidget);
   1.384 +  bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion);
   1.385 +  void DidPaintWindow();
   1.386 +
   1.387 +  // Call this when you need to let the viewmanager know that it now has
   1.388 +  // pending updates.
   1.389 +  void PostPendingUpdate();
   1.390 +
   1.391 +  nsRefPtr<nsDeviceContext> mContext;
   1.392 +  nsIPresShell   *mPresShell;
   1.393 +
   1.394 +  // The size for a resize that we delayed until the root view becomes
   1.395 +  // visible again.
   1.396 +  nsSize            mDelayedResize;
   1.397 +
   1.398 +  nsView           *mRootView;
   1.399 +  // mRootViewManager is a strong ref unless it equals |this|.  It's
   1.400 +  // never null (if we have no ancestors, it will be |this|).
   1.401 +  nsViewManager   *mRootViewManager;
   1.402 +
   1.403 +  // The following members should not be accessed directly except by
   1.404 +  // the root view manager.  Some have accessor functions to enforce
   1.405 +  // this, as noted.
   1.406 +
   1.407 +  int32_t           mRefreshDisableCount;
   1.408 +  // Use IsPainting() and SetPainting() to access mPainting.
   1.409 +  bool              mPainting;
   1.410 +  bool              mRecursiveRefreshPending;
   1.411 +  bool              mHasPendingWidgetGeometryChanges;
   1.412 +  bool              mInScroll;
   1.413 +
   1.414 +  //from here to public should be static and locked... MMP
   1.415 +  static int32_t           mVMCount;        //number of viewmanagers
   1.416 +
   1.417 +  //list of view managers
   1.418 +  static nsVoidArray       *gViewManagers;
   1.419 +};
   1.420 +
   1.421 +/**
   1.422 +   Invalidation model:
   1.423 +
   1.424 +   1) Callers call into the view manager and ask it to invalidate a view.
   1.425 +
   1.426 +   2) The view manager finds the "right" widget for the view, henceforth called
   1.427 +      the root widget.
   1.428 +
   1.429 +   3) The view manager traverses descendants of the root widget and for each
   1.430 +      one that needs invalidation stores the rect to invalidate on the widget's
   1.431 +      view (batching).
   1.432 +
   1.433 +   4) The dirty region is flushed to the right widget when
   1.434 +      ProcessPendingUpdates is called from the RefreshDriver.
   1.435 +
   1.436 +   It's important to note that widgets associated to views outside this view
   1.437 +   manager can end up being invalidated during step 3.  Therefore, the end of a
   1.438 +   view update batch really needs to traverse the entire view tree, to ensure
   1.439 +   that those invalidates happen.
   1.440 +
   1.441 +   To cope with this, invalidation processing and should only happen on the
   1.442 +   root viewmanager.
   1.443 +*/
   1.444 +
   1.445 +#endif  // nsViewManager_h___

mercurial