view/public/nsViewManager.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef nsViewManager_h___
michael@0 7 #define nsViewManager_h___
michael@0 8
michael@0 9 #include "nscore.h"
michael@0 10 #include "nsView.h"
michael@0 11 #include "nsCOMPtr.h"
michael@0 12 #include "nsCRT.h"
michael@0 13 #include "nsVoidArray.h"
michael@0 14 #include "nsDeviceContext.h"
michael@0 15 #include "nsTArray.h"
michael@0 16 #include "mozilla/EventForwards.h"
michael@0 17
michael@0 18 class nsIWidget;
michael@0 19 struct nsRect;
michael@0 20 class nsRegion;
michael@0 21 class nsDeviceContext;
michael@0 22 class nsIPresShell;
michael@0 23
michael@0 24 class nsViewManager MOZ_FINAL
michael@0 25 {
michael@0 26 public:
michael@0 27 friend class nsView;
michael@0 28
michael@0 29 NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
michael@0 30
michael@0 31 NS_INLINE_DECL_REFCOUNTING(nsViewManager)
michael@0 32
michael@0 33 nsViewManager();
michael@0 34 ~nsViewManager();
michael@0 35
michael@0 36 /**
michael@0 37 * Initialize the ViewManager
michael@0 38 * Note: this instance does not hold a reference to the presshell
michael@0 39 * because it holds a reference to this instance.
michael@0 40 * @result The result of the initialization, NS_OK if no errors
michael@0 41 */
michael@0 42 nsresult Init(nsDeviceContext* aContext);
michael@0 43
michael@0 44 /**
michael@0 45 * Create an ordinary view
michael@0 46 * @param aBounds initial bounds for view
michael@0 47 * XXX We should eliminate this parameter; you can set the bounds after CreateView
michael@0 48 * @param aParent intended parent for view. this is not actually set in the
michael@0 49 * nsView through this method. it is only used by the initialization
michael@0 50 * code to walk up the view tree, if necessary, to find resources.
michael@0 51 * XXX We should eliminate this parameter!
michael@0 52 * @param aVisibilityFlag initial visibility state of view
michael@0 53 * XXX We should eliminate this parameter; you can set it after CreateView
michael@0 54 * @result The new view. Never null.
michael@0 55 */
michael@0 56 nsView* CreateView(const nsRect& aBounds,
michael@0 57 nsView* aParent,
michael@0 58 nsViewVisibility aVisibilityFlag = nsViewVisibility_kShow);
michael@0 59
michael@0 60 /**
michael@0 61 * Get the root of the view tree.
michael@0 62 * @result the root view
michael@0 63 */
michael@0 64 nsView* GetRootView() { return mRootView; }
michael@0 65
michael@0 66 /**
michael@0 67 * Set the root of the view tree. Does not destroy the current root view.
michael@0 68 * aView may have a parent view managed by a different view manager.
michael@0 69 * aView may have a widget (anything but printing) or may not (printing).
michael@0 70 * @param aView view to set as root
michael@0 71 */
michael@0 72 void SetRootView(nsView *aView);
michael@0 73
michael@0 74 /**
michael@0 75 * Get the dimensions of the root window. The dimensions are in
michael@0 76 * twips
michael@0 77 * @param aWidth out parameter for width of window in twips
michael@0 78 * @param aHeight out parameter for height of window in twips
michael@0 79 */
michael@0 80 void GetWindowDimensions(nscoord *aWidth, nscoord *aHeight);
michael@0 81
michael@0 82 /**
michael@0 83 * Set the dimensions of the root window.
michael@0 84 * Called if the root window is resized. The dimensions are in
michael@0 85 * twips
michael@0 86 * @param aWidth of window in twips
michael@0 87 * @param aHeight of window in twips
michael@0 88 */
michael@0 89 void SetWindowDimensions(nscoord aWidth, nscoord aHeight);
michael@0 90
michael@0 91 /**
michael@0 92 * Do any resizes that are pending.
michael@0 93 */
michael@0 94 void FlushDelayedResize(bool aDoReflow);
michael@0 95
michael@0 96 /**
michael@0 97 * Called to inform the view manager that the entire area of a view
michael@0 98 * is dirty and needs to be redrawn.
michael@0 99 * @param aView view to paint. should be root view
michael@0 100 */
michael@0 101 void InvalidateView(nsView *aView);
michael@0 102
michael@0 103 /**
michael@0 104 * Called to inform the view manager that some portion of a view is dirty and
michael@0 105 * needs to be redrawn. The rect passed in should be in the view's coordinate
michael@0 106 * space. Does not check for paint suppression.
michael@0 107 * @param aView view to paint. should be root view
michael@0 108 * @param rect rect to mark as damaged
michael@0 109 */
michael@0 110 void InvalidateViewNoSuppression(nsView *aView, const nsRect &aRect);
michael@0 111
michael@0 112 /**
michael@0 113 * Called to inform the view manager that it should invalidate all views.
michael@0 114 */
michael@0 115 void InvalidateAllViews();
michael@0 116
michael@0 117 /**
michael@0 118 * Called to dispatch an event to the appropriate view. Often called
michael@0 119 * as a result of receiving a mouse or keyboard event from the widget
michael@0 120 * event system.
michael@0 121 * @param aEvent event to dispatch
michael@0 122 * @param aViewTarget dispatch the event to this view
michael@0 123 * @param aStatus event handling status
michael@0 124 */
michael@0 125 void DispatchEvent(mozilla::WidgetGUIEvent *aEvent,
michael@0 126 nsView* aViewTarget,
michael@0 127 nsEventStatus* aStatus);
michael@0 128
michael@0 129 /**
michael@0 130 * Given a parent view, insert another view as its child.
michael@0 131 * aSibling and aAbove control the "document order" for the insertion.
michael@0 132 * If aSibling is null, the view is inserted at the end of the document order
michael@0 133 * if aAfter is true, otherwise it is inserted at the beginning.
michael@0 134 * If aSibling is non-null, then if aAfter is true, the view is inserted
michael@0 135 * after the sibling in document order (appearing above the sibling unless
michael@0 136 * overriden by z-order).
michael@0 137 * If it is false, the view is inserted before the sibling.
michael@0 138 * The view manager generates the appopriate dirty regions.
michael@0 139 * @param aParent parent view
michael@0 140 * @param aChild child view
michael@0 141 * @param aSibling sibling view
michael@0 142 * @param aAfter after or before in the document order
michael@0 143 */
michael@0 144 void InsertChild(nsView *aParent, nsView *aChild, nsView *aSibling,
michael@0 145 bool aAfter);
michael@0 146
michael@0 147 void InsertChild(nsView *aParent, nsView *aChild, int32_t aZIndex);
michael@0 148
michael@0 149 /**
michael@0 150 * Remove a specific child view from its parent. This will NOT remove its placeholder
michael@0 151 * if there is one.
michael@0 152 * The view manager generates the appropriate dirty regions.
michael@0 153 * @param aParent parent view
michael@0 154 * @param aChild child view
michael@0 155 */
michael@0 156 void RemoveChild(nsView *aChild);
michael@0 157
michael@0 158 /**
michael@0 159 * Move a view to the specified position, provided in parent coordinates.
michael@0 160 * The new position is the (0, 0) origin for the view's coordinate system.
michael@0 161 * The view's bounds may extend above or to the left of this point.
michael@0 162 * The view manager generates the appropriate dirty regions.
michael@0 163 * @param aView view to move
michael@0 164 * @param aX x value for new view position
michael@0 165 * @param aY y value for new view position
michael@0 166 */
michael@0 167 void MoveViewTo(nsView *aView, nscoord aX, nscoord aY);
michael@0 168
michael@0 169 /**
michael@0 170 * Resize a view. In addition to setting the width and height, you can
michael@0 171 * set the x and y of its bounds relative to its position. Negative x and y
michael@0 172 * will let the view extend above and to the left of the (0,0) point in its
michael@0 173 * coordinate system.
michael@0 174 * The view manager generates the appropriate dirty regions.
michael@0 175 * @param aView view to move
michael@0 176 * @param the new bounds relative to the current position
michael@0 177 * @param RepaintExposedAreaOnly
michael@0 178 * if true Repaint only the expanded or contracted region,
michael@0 179 * if false Repaint the union of the old and new rectangles.
michael@0 180 */
michael@0 181 void ResizeView(nsView *aView, const nsRect &aRect,
michael@0 182 bool aRepaintExposedAreaOnly = false);
michael@0 183
michael@0 184 /**
michael@0 185 * Set the visibility of a view. Hidden views have the effect of hiding
michael@0 186 * their descendants as well. This does not affect painting, so layout
michael@0 187 * is responsible for ensuring that content in hidden views is not
michael@0 188 * painted nor handling events. It does affect the visibility of widgets;
michael@0 189 * if a view is hidden, descendant views with widgets have their widgets
michael@0 190 * hidden.
michael@0 191 * The view manager generates the appropriate dirty regions.
michael@0 192 * @param aView view to change visibility state of
michael@0 193 * @param visible new visibility state
michael@0 194 */
michael@0 195 void SetViewVisibility(nsView *aView, nsViewVisibility aVisible);
michael@0 196
michael@0 197 /**
michael@0 198 * Set the z-index of a view. Positive z-indices mean that a view
michael@0 199 * is above its parent in z-order. Negative z-indices mean that a
michael@0 200 * view is below its parent.
michael@0 201 * The view manager generates the appropriate dirty regions.
michael@0 202 * @param aAutoZIndex indicate that the z-index of a view is "auto". An "auto" z-index
michael@0 203 * means that the view does not define a new stacking context,
michael@0 204 * which means that the z-indicies of the view's children are
michael@0 205 * relative to the view's siblings.
michael@0 206 * @param aView view to change z depth of
michael@0 207 * @param aZindex explicit z depth
michael@0 208 */
michael@0 209 void SetViewZIndex(nsView *aView, bool aAutoZIndex, int32_t aZindex);
michael@0 210
michael@0 211 /**
michael@0 212 * Set whether the view "floats" above all other views,
michael@0 213 * which tells the compositor not to consider higher views in
michael@0 214 * the view hierarchy that would geometrically intersect with
michael@0 215 * this view. This is a hack, but it fixes some problems with
michael@0 216 * views that need to be drawn in front of all other views.
michael@0 217 */
michael@0 218 void SetViewFloating(nsView *aView, bool aFloatingView);
michael@0 219
michael@0 220 /**
michael@0 221 * Set the presshell associated with this manager
michael@0 222 * @param aPresShell - new presshell
michael@0 223 */
michael@0 224 void SetPresShell(nsIPresShell *aPresShell) { mPresShell = aPresShell; }
michael@0 225
michael@0 226 /**
michael@0 227 * Get the pres shell associated with this manager
michael@0 228 */
michael@0 229 nsIPresShell* GetPresShell() { return mPresShell; }
michael@0 230
michael@0 231 /**
michael@0 232 * Get the device context associated with this manager
michael@0 233 */
michael@0 234 nsDeviceContext* GetDeviceContext() const
michael@0 235 {
michael@0 236 return mContext;
michael@0 237 }
michael@0 238
michael@0 239 /**
michael@0 240 * A stack class for disallowing changes that would enter painting. For
michael@0 241 * example, popup widgets shouldn't be resized during reflow, since doing so
michael@0 242 * might cause synchronous painting inside reflow which is forbidden.
michael@0 243 * While refresh is disabled, widget geometry changes are deferred and will
michael@0 244 * be handled later, either from the refresh driver or from an NS_WILL_PAINT
michael@0 245 * event.
michael@0 246 * We don't want to defer widget geometry changes all the time. Resizing a
michael@0 247 * popup from script doesn't need to be deferred, for example, especially
michael@0 248 * since popup widget geometry is observable from script and expected to
michael@0 249 * update synchronously.
michael@0 250 */
michael@0 251 class MOZ_STACK_CLASS AutoDisableRefresh {
michael@0 252 public:
michael@0 253 AutoDisableRefresh(nsViewManager* aVM) {
michael@0 254 if (aVM) {
michael@0 255 mRootVM = aVM->IncrementDisableRefreshCount();
michael@0 256 }
michael@0 257 }
michael@0 258 ~AutoDisableRefresh() {
michael@0 259 if (mRootVM) {
michael@0 260 mRootVM->DecrementDisableRefreshCount();
michael@0 261 }
michael@0 262 }
michael@0 263 private:
michael@0 264 AutoDisableRefresh(const AutoDisableRefresh& aOther);
michael@0 265 const AutoDisableRefresh& operator=(const AutoDisableRefresh& aOther);
michael@0 266
michael@0 267 nsRefPtr<nsViewManager> mRootVM;
michael@0 268 };
michael@0 269
michael@0 270 private:
michael@0 271 friend class AutoDisableRefresh;
michael@0 272
michael@0 273 nsViewManager* IncrementDisableRefreshCount();
michael@0 274 void DecrementDisableRefreshCount();
michael@0 275
michael@0 276 public:
michael@0 277 /**
michael@0 278 * Retrieve the widget at the root of the nearest enclosing
michael@0 279 * view manager whose root view has a widget.
michael@0 280 */
michael@0 281 void GetRootWidget(nsIWidget **aWidget);
michael@0 282
michael@0 283 /**
michael@0 284 * Indicate whether the viewmanager is currently painting
michael@0 285 *
michael@0 286 * @param aPainting true if the viewmanager is painting
michael@0 287 * false otherwise
michael@0 288 */
michael@0 289 void IsPainting(bool& aIsPainting);
michael@0 290
michael@0 291 /**
michael@0 292 * Retrieve the time of the last user event. User events
michael@0 293 * include mouse and keyboard events. The viewmanager
michael@0 294 * saves the time of the last user event.
michael@0 295 *
michael@0 296 * @param aTime Last user event time in microseconds
michael@0 297 */
michael@0 298 void GetLastUserEventTime(uint32_t& aTime);
michael@0 299
michael@0 300 /**
michael@0 301 * Find the nearest display root view for the view aView. This is the view for
michael@0 302 * the nearest enclosing popup or the root view for the root document.
michael@0 303 */
michael@0 304 static nsView* GetDisplayRootFor(nsView* aView);
michael@0 305
michael@0 306 /**
michael@0 307 * Flush the accumulated dirty region to the widget and update widget
michael@0 308 * geometry.
michael@0 309 */
michael@0 310 void ProcessPendingUpdates();
michael@0 311
michael@0 312 /**
michael@0 313 * Just update widget geometry without flushing the dirty region
michael@0 314 */
michael@0 315 void UpdateWidgetGeometry();
michael@0 316
michael@0 317 int32_t AppUnitsPerDevPixel() const
michael@0 318 {
michael@0 319 return mContext->AppUnitsPerDevPixel();
michael@0 320 }
michael@0 321
michael@0 322 private:
michael@0 323 static uint32_t gLastUserEventTime;
michael@0 324
michael@0 325 /* Update the cached RootViewManager pointer on this view manager. */
michael@0 326 void InvalidateHierarchy();
michael@0 327 void FlushPendingInvalidates();
michael@0 328
michael@0 329 void ProcessPendingUpdatesForView(nsView *aView,
michael@0 330 bool aFlushDirtyRegion = true);
michael@0 331 void ProcessPendingUpdatesRecurse(nsView* aView,
michael@0 332 nsTArray<nsCOMPtr<nsIWidget> >& aWidgets);
michael@0 333 void ProcessPendingUpdatesPaint(nsIWidget* aWidget);
michael@0 334
michael@0 335 void FlushDirtyRegionToWidget(nsView* aView);
michael@0 336 /**
michael@0 337 * Call WillPaint() on all view observers under this vm root.
michael@0 338 */
michael@0 339 void CallWillPaintOnObservers();
michael@0 340 void ReparentChildWidgets(nsView* aView, nsIWidget *aNewWidget);
michael@0 341 void ReparentWidgets(nsView* aView, nsView *aParent);
michael@0 342 void InvalidateWidgetArea(nsView *aWidgetView, const nsRegion &aDamagedRegion);
michael@0 343
michael@0 344 void InvalidateViews(nsView *aView);
michael@0 345
michael@0 346 // aView is the view for aWidget and aRegion is relative to aWidget.
michael@0 347 void Refresh(nsView *aView, const nsIntRegion& aRegion);
michael@0 348
michael@0 349 // Utilities
michael@0 350
michael@0 351 bool IsViewInserted(nsView *aView);
michael@0 352
michael@0 353 /**
michael@0 354 * Intersects aRect with aView's bounds and then transforms it from aView's
michael@0 355 * coordinate system to the coordinate system of the widget attached to
michael@0 356 * aView.
michael@0 357 */
michael@0 358 nsIntRect ViewToWidget(nsView *aView, const nsRect &aRect) const;
michael@0 359
michael@0 360 void DoSetWindowDimensions(nscoord aWidth, nscoord aHeight);
michael@0 361
michael@0 362 bool IsPainting() const {
michael@0 363 return RootViewManager()->mPainting;
michael@0 364 }
michael@0 365
michael@0 366 void SetPainting(bool aPainting) {
michael@0 367 RootViewManager()->mPainting = aPainting;
michael@0 368 }
michael@0 369
michael@0 370 void InvalidateView(nsView *aView, const nsRect &aRect);
michael@0 371
michael@0 372 nsViewManager* RootViewManager() const { return mRootViewManager; }
michael@0 373 bool IsRootVM() const { return this == RootViewManager(); }
michael@0 374
michael@0 375 // Whether synchronous painting is allowed at the moment. For example,
michael@0 376 // widget geometry changes can cause synchronous painting, so they need to
michael@0 377 // be deferred while refresh is disabled.
michael@0 378 bool IsPaintingAllowed() { return RootViewManager()->mRefreshDisableCount == 0; }
michael@0 379
michael@0 380 void WillPaintWindow(nsIWidget* aWidget);
michael@0 381 bool PaintWindow(nsIWidget* aWidget, nsIntRegion aRegion);
michael@0 382 void DidPaintWindow();
michael@0 383
michael@0 384 // Call this when you need to let the viewmanager know that it now has
michael@0 385 // pending updates.
michael@0 386 void PostPendingUpdate();
michael@0 387
michael@0 388 nsRefPtr<nsDeviceContext> mContext;
michael@0 389 nsIPresShell *mPresShell;
michael@0 390
michael@0 391 // The size for a resize that we delayed until the root view becomes
michael@0 392 // visible again.
michael@0 393 nsSize mDelayedResize;
michael@0 394
michael@0 395 nsView *mRootView;
michael@0 396 // mRootViewManager is a strong ref unless it equals |this|. It's
michael@0 397 // never null (if we have no ancestors, it will be |this|).
michael@0 398 nsViewManager *mRootViewManager;
michael@0 399
michael@0 400 // The following members should not be accessed directly except by
michael@0 401 // the root view manager. Some have accessor functions to enforce
michael@0 402 // this, as noted.
michael@0 403
michael@0 404 int32_t mRefreshDisableCount;
michael@0 405 // Use IsPainting() and SetPainting() to access mPainting.
michael@0 406 bool mPainting;
michael@0 407 bool mRecursiveRefreshPending;
michael@0 408 bool mHasPendingWidgetGeometryChanges;
michael@0 409 bool mInScroll;
michael@0 410
michael@0 411 //from here to public should be static and locked... MMP
michael@0 412 static int32_t mVMCount; //number of viewmanagers
michael@0 413
michael@0 414 //list of view managers
michael@0 415 static nsVoidArray *gViewManagers;
michael@0 416 };
michael@0 417
michael@0 418 /**
michael@0 419 Invalidation model:
michael@0 420
michael@0 421 1) Callers call into the view manager and ask it to invalidate a view.
michael@0 422
michael@0 423 2) The view manager finds the "right" widget for the view, henceforth called
michael@0 424 the root widget.
michael@0 425
michael@0 426 3) The view manager traverses descendants of the root widget and for each
michael@0 427 one that needs invalidation stores the rect to invalidate on the widget's
michael@0 428 view (batching).
michael@0 429
michael@0 430 4) The dirty region is flushed to the right widget when
michael@0 431 ProcessPendingUpdates is called from the RefreshDriver.
michael@0 432
michael@0 433 It's important to note that widgets associated to views outside this view
michael@0 434 manager can end up being invalidated during step 3. Therefore, the end of a
michael@0 435 view update batch really needs to traverse the entire view tree, to ensure
michael@0 436 that those invalidates happen.
michael@0 437
michael@0 438 To cope with this, invalidation processing and should only happen on the
michael@0 439 root viewmanager.
michael@0 440 */
michael@0 441
michael@0 442 #endif // nsViewManager_h___

mercurial