LCOV - code coverage report
Current view: directory - view/src - nsView.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 536 0 0.0 %
Date: 2012-06-02 Functions: 65 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozilla.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      26                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : #include "nsView.h"
      39                 : #include "nsIWidget.h"
      40                 : #include "nsWidgetsCID.h"
      41                 : #include "nsViewManager.h"
      42                 : #include "nsGUIEvent.h"
      43                 : #include "nsIComponentManager.h"
      44                 : #include "nsGfxCIID.h"
      45                 : #include "nsIInterfaceRequestor.h"
      46                 : 
      47                 : //mmptemp
      48                 : 
      49                 : static nsEventStatus HandleEvent(nsGUIEvent *aEvent);
      50                 : 
      51                 : 
      52                 : //#define SHOW_VIEW_BORDERS
      53                 : 
      54                 : #define VIEW_WRAPPER_IID \
      55                 :   { 0xbf4e1841, 0xe9ec, 0x47f2, \
      56                 :     { 0xb4, 0x77, 0x0f, 0xf6, 0x0f, 0x5a, 0xac, 0xbd } }
      57                 : 
      58                 : /**
      59                 :  * nsISupports-derived helper class that allows to store and get a view
      60                 :  */
      61                 : class ViewWrapper : public nsIInterfaceRequestor
      62                 : {
      63                 :   public:
      64                 :     NS_DECLARE_STATIC_IID_ACCESSOR(VIEW_WRAPPER_IID)
      65                 :     NS_DECL_ISUPPORTS
      66                 :     NS_DECL_NSIINTERFACEREQUESTOR
      67                 : 
      68               0 :     ViewWrapper(nsView* aView) : mView(aView) {}
      69                 : 
      70               0 :     nsView* GetView() { return mView; }
      71                 :   private:
      72                 :     nsView* mView;
      73                 : };
      74                 : 
      75                 : NS_DEFINE_STATIC_IID_ACCESSOR(ViewWrapper, VIEW_WRAPPER_IID)
      76                 : 
      77               0 : NS_IMPL_ADDREF(ViewWrapper)
      78               0 : NS_IMPL_RELEASE(ViewWrapper)
      79                 : #ifndef DEBUG
      80                 : NS_IMPL_QUERY_INTERFACE2(ViewWrapper, ViewWrapper, nsIInterfaceRequestor)
      81                 : 
      82                 : #else
      83               0 : NS_IMETHODIMP ViewWrapper::QueryInterface(REFNSIID aIID, void** aInstancePtr)
      84                 : {
      85               0 :   NS_ENSURE_ARG_POINTER(aInstancePtr);
      86                 : 
      87               0 :   NS_ASSERTION(!aIID.Equals(NS_GET_IID(nsIView)),
      88                 :                "Someone expects a viewwrapper to be a view!");
      89                 :   
      90               0 :   *aInstancePtr = nsnull;
      91                 :   
      92               0 :   if (aIID.Equals(NS_GET_IID(nsISupports))) {
      93               0 :     *aInstancePtr = static_cast<nsISupports*>(this);
      94                 :   }
      95               0 :   else if (aIID.Equals(NS_GET_IID(ViewWrapper))) {
      96               0 :     *aInstancePtr = this;
      97                 :   }
      98               0 :   else if (aIID.Equals(NS_GET_IID(nsIInterfaceRequestor))) {
      99               0 :     *aInstancePtr = this;
     100                 :   }
     101                 : 
     102                 : 
     103               0 :   if (*aInstancePtr) {
     104               0 :     AddRef();
     105               0 :     return NS_OK;
     106                 :   }
     107                 : 
     108               0 :   return NS_NOINTERFACE;
     109                 : }
     110                 : #endif
     111                 : 
     112               0 : NS_IMETHODIMP ViewWrapper::GetInterface(REFNSIID aIID, void** aInstancePtr)
     113                 : {
     114               0 :   if (aIID.Equals(NS_GET_IID(nsIView))) {
     115               0 :     *aInstancePtr = mView;
     116               0 :     return NS_OK;
     117                 :   }
     118               0 :   return QueryInterface(aIID, aInstancePtr);
     119                 : }
     120                 : 
     121                 : /**
     122                 :  * Given a widget, returns the stored ViewWrapper on it, or NULL if no
     123                 :  * ViewWrapper is there.
     124                 :  */
     125               0 : static ViewWrapper* GetWrapperFor(nsIWidget* aWidget)
     126                 : {
     127                 :   // The widget's client data points back to the owning view
     128               0 :   if (aWidget) {
     129                 :     void* clientData;
     130               0 :     aWidget->GetClientData(clientData);
     131               0 :     nsISupports* data = (nsISupports*)clientData;
     132                 :     
     133               0 :     if (data) {
     134                 :       ViewWrapper* wrapper;
     135               0 :       CallQueryInterface(data, &wrapper);
     136                 :       // Give a weak reference to the caller. There will still be at least one
     137                 :       // reference left, since the wrapper was addrefed when set on the widget.
     138               0 :       if (wrapper)
     139               0 :         wrapper->Release();
     140               0 :       return wrapper;
     141                 :     }
     142                 :   }
     143               0 :   return nsnull;
     144                 : }
     145                 : 
     146                 : // Main events handler
     147               0 : static nsEventStatus HandleEvent(nsGUIEvent *aEvent)
     148                 : {
     149                 : #if 0
     150                 :   printf(" %d %d %d (%d,%d) \n", aEvent->widget, aEvent->message);
     151                 : #endif
     152               0 :   nsEventStatus result = nsEventStatus_eIgnore;
     153               0 :   nsView *view = nsView::GetViewFor(aEvent->widget);
     154                 : 
     155               0 :   if (view)
     156                 :   {
     157               0 :     nsCOMPtr<nsIViewManager> vm = view->GetViewManager();
     158               0 :     vm->DispatchEvent(aEvent, view, &result);
     159                 :   }
     160                 : 
     161               0 :   return result;
     162                 : }
     163                 : 
     164                 : // Attached widget event helpers
     165               0 : static ViewWrapper* GetAttachedWrapperFor(nsIWidget* aWidget)
     166                 : {
     167               0 :   NS_PRECONDITION(nsnull != aWidget, "null widget ptr");
     168               0 :   return aWidget->GetAttachedViewPtr();
     169                 : }
     170                 : 
     171               0 : static nsView* GetAttachedViewFor(nsIWidget* aWidget)
     172                 : {           
     173               0 :   NS_PRECONDITION(nsnull != aWidget, "null widget ptr");
     174                 : 
     175               0 :   ViewWrapper* wrapper = GetAttachedWrapperFor(aWidget);
     176               0 :   if (!wrapper)
     177               0 :     return nsnull;
     178               0 :   return wrapper->GetView();
     179                 : }
     180                 : 
     181                 : // event handler
     182               0 : static nsEventStatus AttachedHandleEvent(nsGUIEvent *aEvent)
     183                 : { 
     184               0 :   nsEventStatus result = nsEventStatus_eIgnore;
     185               0 :   nsView *view = GetAttachedViewFor(aEvent->widget);
     186                 : 
     187               0 :   if (view)
     188                 :   {
     189               0 :     nsCOMPtr<nsIViewManager> vm = view->GetViewManager();
     190               0 :     vm->DispatchEvent(aEvent, view, &result);
     191                 :   }
     192                 : 
     193               0 :   return result;
     194                 : }
     195                 : 
     196               0 : nsView::nsView(nsViewManager* aViewManager, nsViewVisibility aVisibility)
     197                 : {
     198               0 :   MOZ_COUNT_CTOR(nsView);
     199                 : 
     200               0 :   mVis = aVisibility;
     201                 :   // Views should be transparent by default. Not being transparent is
     202                 :   // a promise that the view will paint all its pixels opaquely. Views
     203                 :   // should make this promise explicitly by calling
     204                 :   // SetViewContentTransparency.
     205               0 :   mVFlags = 0;
     206               0 :   mViewManager = aViewManager;
     207               0 :   mDirtyRegion = nsnull;
     208               0 :   mDeletionObserver = nsnull;
     209               0 :   mHaveInvalidationDimensions = false;
     210               0 :   mWidgetIsTopLevel = false;
     211               0 : }
     212                 : 
     213               0 : void nsView::DropMouseGrabbing()
     214                 : {
     215               0 :   nsIPresShell* presShell = mViewManager->GetPresShell();
     216               0 :   if (presShell)
     217               0 :     presShell->ClearMouseCaptureOnView(this);
     218               0 : }
     219                 : 
     220               0 : nsView::~nsView()
     221                 : {
     222               0 :   MOZ_COUNT_DTOR(nsView);
     223                 : 
     224               0 :   while (GetFirstChild())
     225                 :   {
     226               0 :     nsView* child = GetFirstChild();
     227               0 :     if (child->GetViewManager() == mViewManager) {
     228               0 :       child->Destroy();
     229                 :     } else {
     230                 :       // just unhook it. Someone else will want to destroy this.
     231               0 :       RemoveChild(child);
     232                 :     }
     233                 :   }
     234                 : 
     235               0 :   if (mViewManager)
     236                 :   {
     237               0 :     DropMouseGrabbing();
     238                 :   
     239               0 :     nsView *rootView = mViewManager->GetRootViewImpl();
     240                 :     
     241               0 :     if (rootView)
     242                 :     {
     243                 :       // Root views can have parents!
     244               0 :       if (mParent)
     245                 :       {
     246               0 :         mViewManager->RemoveChild(this);
     247                 :       }
     248                 : 
     249               0 :       if (rootView == this)
     250                 :       {
     251                 :         // Inform the view manager that the root view has gone away...
     252               0 :         mViewManager->SetRootView(nsnull);
     253                 :       }
     254                 :     }
     255               0 :     else if (mParent)
     256                 :     {
     257               0 :       mParent->RemoveChild(this);
     258                 :     }
     259                 :     
     260               0 :     mViewManager = nsnull;
     261                 :   }
     262               0 :   else if (mParent)
     263                 :   {
     264               0 :     mParent->RemoveChild(this);
     265                 :   }
     266                 : 
     267                 :   // Destroy and release the widget
     268               0 :   DestroyWidget();
     269                 : 
     270               0 :   delete mDirtyRegion;
     271                 : 
     272               0 :   if (mDeletionObserver) {
     273               0 :     mDeletionObserver->Clear();
     274                 :   }
     275               0 : }
     276                 : 
     277               0 : void nsView::DestroyWidget()
     278                 : {
     279               0 :   if (mWindow)
     280                 :   {
     281                 :     // Release memory for the view wrapper
     282               0 :     ViewWrapper* wrapper = GetWrapperFor(mWindow);
     283               0 :     NS_IF_RELEASE(wrapper);
     284                 : 
     285                 :     // If we are not attached to a base window, we're going to tear down our
     286                 :     // widget here. However, if we're attached to somebody elses widget, we
     287                 :     // want to leave the widget alone: don't reset the client data or call
     288                 :     // Destroy. Just clear our event view ptr and free our reference to it. 
     289               0 :     if (mWidgetIsTopLevel) {
     290               0 :       ViewWrapper* wrapper = GetAttachedWrapperFor(mWindow);
     291               0 :       NS_IF_RELEASE(wrapper);
     292                 : 
     293               0 :       mWindow->SetAttachedViewPtr(nsnull);
     294                 :     }
     295                 :     else {
     296               0 :       mWindow->SetClientData(nsnull);
     297               0 :       mWindow->Destroy();
     298                 :     }
     299                 : 
     300               0 :     NS_RELEASE(mWindow);
     301                 :   }
     302               0 : }
     303                 : 
     304               0 : nsresult nsView::QueryInterface(const nsIID& aIID, void** aInstancePtr)
     305                 : {
     306               0 :   if (nsnull == aInstancePtr) {
     307               0 :     return NS_ERROR_NULL_POINTER;
     308                 :   }
     309                 : 
     310               0 :   NS_ASSERTION(!aIID.Equals(NS_GET_IID(nsISupports)),
     311                 :                "Someone expects views to be ISupports-derived!");
     312                 :   
     313               0 :   *aInstancePtr = nsnull;
     314                 :   
     315               0 :   if (aIID.Equals(NS_GET_IID(nsIView))) {
     316               0 :     *aInstancePtr = (void*)(nsIView*)this;
     317               0 :     return NS_OK;
     318                 :   }
     319                 : 
     320               0 :   return NS_NOINTERFACE;
     321                 : }
     322                 : 
     323               0 : nsIView* nsIView::GetViewFor(nsIWidget* aWidget)
     324                 : {           
     325               0 :   NS_PRECONDITION(nsnull != aWidget, "null widget ptr");
     326                 : 
     327               0 :   ViewWrapper* wrapper = GetWrapperFor(aWidget);
     328                 : 
     329               0 :   if (!wrapper) {
     330               0 :     wrapper = GetAttachedWrapperFor(aWidget);
     331                 :   }
     332                 : 
     333               0 :   if (wrapper) {
     334               0 :     return wrapper->GetView();
     335                 :   }
     336                 : 
     337               0 :   return nsnull;
     338                 : }
     339                 : 
     340               0 : void nsIView::Destroy()
     341                 : {
     342               0 :   delete this;
     343               0 : }
     344                 : 
     345               0 : void nsView::SetPosition(nscoord aX, nscoord aY)
     346                 : {
     347               0 :   mDimBounds.x += aX - mPosX;
     348               0 :   mDimBounds.y += aY - mPosY;
     349               0 :   mPosX = aX;
     350               0 :   mPosY = aY;
     351                 : 
     352               0 :   NS_ASSERTION(GetParent() || (aX == 0 && aY == 0),
     353                 :                "Don't try to move the root widget to something non-zero");
     354                 : 
     355               0 :   ResetWidgetBounds(true, false);
     356               0 : }
     357                 : 
     358               0 : void nsIView::SetInvalidationDimensions(const nsRect* aRect)
     359                 : {
     360               0 :   return Impl()->SetInvalidationDimensions(aRect);
     361                 : }
     362                 : 
     363               0 : void nsView::ResetWidgetBounds(bool aRecurse, bool aForceSync)
     364                 : {
     365               0 :   if (mWindow) {
     366               0 :     if (!aForceSync) {
     367                 :       // Don't change widget geometry synchronously, since that can
     368                 :       // cause synchronous painting.
     369               0 :       mViewManager->PostPendingUpdate();
     370                 :     } else {
     371               0 :       DoResetWidgetBounds(false, true);
     372                 :     }
     373               0 :     return;
     374                 :   }
     375                 : 
     376               0 :   if (aRecurse) {
     377                 :     // reposition any widgets under this view
     378               0 :     for (nsView* v = GetFirstChild(); v; v = v->GetNextSibling()) {
     379               0 :       v->ResetWidgetBounds(true, aForceSync);
     380                 :     }
     381                 :   }
     382                 : }
     383                 : 
     384               0 : bool nsIView::IsEffectivelyVisible()
     385                 : {
     386               0 :   for (nsIView* v = this; v; v = v->mParent) {
     387               0 :     if (v->GetVisibility() == nsViewVisibility_kHide)
     388               0 :       return false;
     389                 :   }
     390               0 :   return true;
     391                 : }
     392                 : 
     393               0 : nsIntRect nsIView::CalcWidgetBounds(nsWindowType aType)
     394                 : {
     395               0 :   PRInt32 p2a = mViewManager->AppUnitsPerDevPixel();
     396                 : 
     397               0 :   nsRect viewBounds(mDimBounds);
     398                 : 
     399               0 :   nsView* parent = GetParent()->Impl();
     400               0 :   if (parent) {
     401               0 :     nsPoint offset;
     402               0 :     nsIWidget* parentWidget = parent->GetNearestWidget(&offset, p2a);
     403                 :     // make viewBounds be relative to the parent widget, in appunits
     404               0 :     viewBounds += offset;
     405                 : 
     406               0 :     if (parentWidget && aType == eWindowType_popup &&
     407               0 :         IsEffectivelyVisible()) {
     408                 :       // put offset into screen coordinates. (based on client area origin)
     409               0 :       nsIntPoint screenPoint = parentWidget->WidgetToScreenOffset();
     410                 :       viewBounds += nsPoint(NSIntPixelsToAppUnits(screenPoint.x, p2a),
     411               0 :                             NSIntPixelsToAppUnits(screenPoint.y, p2a));
     412                 :     }
     413                 :   }
     414                 : 
     415                 :   // Compute widget bounds in device pixels
     416               0 :   nsIntRect newBounds = viewBounds.ToNearestPixels(p2a);
     417                 : 
     418                 :   // Compute where the top-left of our widget ended up relative to the parent
     419                 :   // widget, in appunits.
     420                 :   nsPoint roundedOffset(NSIntPixelsToAppUnits(newBounds.x, p2a),
     421               0 :                         NSIntPixelsToAppUnits(newBounds.y, p2a));
     422                 : 
     423                 :   // mViewToWidgetOffset is added to coordinates relative to the view origin
     424                 :   // to get coordinates relative to the widget.
     425                 :   // The view origin, relative to the parent widget, is at
     426                 :   // (mPosX,mPosY) - mDimBounds.TopLeft() + viewBounds.TopLeft().
     427                 :   // Our widget, relative to the parent widget, is roundedOffset.
     428                 :   mViewToWidgetOffset = nsPoint(mPosX, mPosY)
     429               0 :     - mDimBounds.TopLeft() + viewBounds.TopLeft() - roundedOffset;
     430                 : 
     431                 :   return newBounds;
     432                 : }
     433                 : 
     434               0 : void nsView::DoResetWidgetBounds(bool aMoveOnly,
     435                 :                                  bool aInvalidateChangedSize) {
     436                 :   // The geometry of a root view's widget is controlled externally,
     437                 :   // NOT by sizing or positioning the view
     438               0 :   if (mViewManager->GetRootViewImpl() == this) {
     439               0 :     return;
     440                 :   }
     441                 :   
     442               0 :   nsIntRect curBounds;
     443               0 :   mWindow->GetClientBounds(curBounds);
     444                 : 
     445                 :   nsWindowType type;
     446               0 :   mWindow->GetWindowType(type);
     447                 : 
     448               0 :   if (curBounds.IsEmpty() && mDimBounds.IsEmpty() && type == eWindowType_popup) {
     449                 :     // Don't manipulate empty popup widgets. For example there's no point
     450                 :     // moving hidden comboboxes around, or doing X server roundtrips
     451                 :     // to compute their true screen position. This could mean that WidgetToScreen
     452                 :     // operations on these widgets don't return up-to-date values, but popup
     453                 :     // positions aren't reliable anyway because of correction to be on or off-screen.
     454               0 :     return;
     455                 :   }
     456                 : 
     457               0 :   NS_PRECONDITION(mWindow, "Why was this called??");
     458                 : 
     459               0 :   nsIntRect newBounds = CalcWidgetBounds(type);
     460                 : 
     461               0 :   bool changedPos = curBounds.TopLeft() != newBounds.TopLeft();
     462               0 :   bool changedSize = curBounds.Size() != newBounds.Size();
     463                 : 
     464                 :   // Child views are never attached to top level widgets, this is safe.
     465               0 :   if (changedPos) {
     466               0 :     if (changedSize && !aMoveOnly) {
     467                 :       mWindow->ResizeClient(newBounds.x, newBounds.y,
     468                 :                             newBounds.width, newBounds.height,
     469               0 :                             aInvalidateChangedSize);
     470                 :     } else {
     471               0 :       mWindow->MoveClient(newBounds.x, newBounds.y);
     472                 :     }
     473                 :   } else {
     474               0 :     if (changedSize && !aMoveOnly) {
     475                 :       mWindow->ResizeClient(newBounds.width, newBounds.height,
     476               0 :                             aInvalidateChangedSize);
     477                 :     } // else do nothing!
     478                 :   }
     479                 : }
     480                 : 
     481               0 : void nsView::SetDimensions(const nsRect& aRect, bool aPaint, bool aResizeWidget)
     482                 : {
     483               0 :   nsRect dims = aRect;
     484               0 :   dims.MoveBy(mPosX, mPosY);
     485                 : 
     486                 :   // Don't use nsRect's operator== here, since it returns true when
     487                 :   // both rects are empty even if they have different widths and we
     488                 :   // have cases where that sort of thing matters to us.
     489               0 :   if (mDimBounds.TopLeft() == dims.TopLeft() &&
     490               0 :       mDimBounds.Size() == dims.Size()) {
     491                 :     return;
     492                 :   }
     493                 : 
     494               0 :   mDimBounds = dims;
     495                 : 
     496               0 :   if (aResizeWidget) {
     497               0 :     ResetWidgetBounds(false, false);
     498                 :   }
     499                 : }
     500                 : 
     501               0 : void nsView::SetInvalidationDimensions(const nsRect* aRect)
     502                 : {
     503               0 :   if ((mHaveInvalidationDimensions = !!aRect)) {
     504               0 :     mInvalidationDimensions = *aRect;
     505                 :   }
     506               0 : }
     507                 : 
     508               0 : void nsView::NotifyEffectiveVisibilityChanged(bool aEffectivelyVisible)
     509                 : {
     510               0 :   if (!aEffectivelyVisible)
     511                 :   {
     512               0 :     DropMouseGrabbing();
     513                 :   }
     514                 : 
     515               0 :   if (nsnull != mWindow)
     516                 :   {
     517               0 :     if (aEffectivelyVisible)
     518                 :     {
     519               0 :       DoResetWidgetBounds(false, true);
     520               0 :       mWindow->Show(true);
     521                 :     }
     522                 :     else
     523               0 :       mWindow->Show(false);
     524                 :   }
     525                 : 
     526               0 :   for (nsView* child = mFirstChild; child; child = child->mNextSibling) {
     527               0 :     if (child->mVis == nsViewVisibility_kHide) {
     528                 :       // It was effectively hidden and still is
     529               0 :       continue;
     530                 :     }
     531                 :     // Our child is visible if we are
     532               0 :     child->NotifyEffectiveVisibilityChanged(aEffectivelyVisible);
     533                 :   }
     534               0 : }
     535                 : 
     536               0 : NS_IMETHODIMP nsView::SetVisibility(nsViewVisibility aVisibility)
     537                 : {
     538               0 :   mVis = aVisibility;
     539               0 :   NotifyEffectiveVisibilityChanged(IsEffectivelyVisible());
     540               0 :   return NS_OK;
     541                 : }
     542                 : 
     543               0 : NS_IMETHODIMP nsView::SetFloating(bool aFloatingView)
     544                 : {
     545               0 :         if (aFloatingView)
     546               0 :                 mVFlags |= NS_VIEW_FLAG_FLOATING;
     547                 :         else
     548               0 :                 mVFlags &= ~NS_VIEW_FLAG_FLOATING;
     549                 : 
     550                 : #if 0
     551                 :         // recursively make all sub-views "floating" grr.
     552                 :         for (nsView* child = mFirstChild; chlid; child = child->GetNextSibling()) {
     553                 :                 child->SetFloating(aFloatingView);
     554                 :         }
     555                 : #endif
     556                 : 
     557               0 :         return NS_OK;
     558                 : }
     559                 : 
     560               0 : void nsView::InvalidateHierarchy(nsViewManager *aViewManagerParent)
     561                 : {
     562               0 :   if (mViewManager->GetRootViewImpl() == this)
     563               0 :     mViewManager->InvalidateHierarchy();
     564                 : 
     565               0 :   for (nsView *child = mFirstChild; child; child = child->GetNextSibling())
     566               0 :     child->InvalidateHierarchy(aViewManagerParent);
     567               0 : }
     568                 : 
     569               0 : void nsView::InsertChild(nsView *aChild, nsView *aSibling)
     570                 : {
     571               0 :   NS_PRECONDITION(nsnull != aChild, "null ptr");
     572                 : 
     573               0 :   if (nsnull != aChild)
     574                 :   {
     575               0 :     if (nsnull != aSibling)
     576                 :     {
     577                 : #ifdef NS_DEBUG
     578               0 :       NS_ASSERTION(aSibling->GetParent() == this, "tried to insert view with invalid sibling");
     579                 : #endif
     580                 :       //insert after sibling
     581               0 :       aChild->SetNextSibling(aSibling->GetNextSibling());
     582               0 :       aSibling->SetNextSibling(aChild);
     583                 :     }
     584                 :     else
     585                 :     {
     586               0 :       aChild->SetNextSibling(mFirstChild);
     587               0 :       mFirstChild = aChild;
     588                 :     }
     589               0 :     aChild->SetParent(this);
     590                 : 
     591                 :     // If we just inserted a root view, then update the RootViewManager
     592                 :     // on all view managers in the new subtree.
     593                 : 
     594               0 :     nsViewManager *vm = aChild->GetViewManager();
     595               0 :     if (vm->GetRootViewImpl() == aChild)
     596                 :     {
     597               0 :       aChild->InvalidateHierarchy(nsnull); // don't care about releasing grabs
     598                 :     }
     599                 :   }
     600               0 : }
     601                 : 
     602               0 : void nsView::RemoveChild(nsView *child)
     603                 : {
     604               0 :   NS_PRECONDITION(nsnull != child, "null ptr");
     605                 : 
     606               0 :   if (nsnull != child)
     607                 :   {
     608               0 :     nsView* prevKid = nsnull;
     609               0 :     nsView* kid = mFirstChild;
     610               0 :     bool found = false;
     611               0 :     while (nsnull != kid) {
     612               0 :       if (kid == child) {
     613               0 :         if (nsnull != prevKid) {
     614               0 :           prevKid->SetNextSibling(kid->GetNextSibling());
     615                 :         } else {
     616               0 :           mFirstChild = kid->GetNextSibling();
     617                 :         }
     618               0 :         child->SetParent(nsnull);
     619               0 :         found = true;
     620               0 :         break;
     621                 :       }
     622               0 :       prevKid = kid;
     623               0 :             kid = kid->GetNextSibling();
     624                 :     }
     625               0 :     NS_ASSERTION(found, "tried to remove non child");
     626                 : 
     627                 :     // If we just removed a root view, then update the RootViewManager
     628                 :     // on all view managers in the removed subtree.
     629                 : 
     630               0 :     nsViewManager *vm = child->GetViewManager();
     631               0 :     if (vm->GetRootViewImpl() == child)
     632                 :     {
     633               0 :       child->InvalidateHierarchy(GetViewManager());
     634                 :     }
     635                 :   }
     636               0 : }
     637                 : 
     638                 : // Native widgets ultimately just can't deal with the awesome power of
     639                 : // CSS2 z-index. However, we set the z-index on the widget anyway
     640                 : // because in many simple common cases the widgets do end up in the
     641                 : // right order. We set each widget's z-index to the z-index of the
     642                 : // nearest ancestor that has non-auto z-index.
     643               0 : static void UpdateNativeWidgetZIndexes(nsView* aView, PRInt32 aZIndex)
     644                 : {
     645               0 :   if (aView->HasWidget()) {
     646               0 :     nsIWidget* widget = aView->GetWidget();
     647                 :     PRInt32 curZ;
     648               0 :     widget->GetZIndex(&curZ);
     649               0 :     if (curZ != aZIndex) {
     650               0 :       widget->SetZIndex(aZIndex);
     651                 :     }
     652                 :   } else {
     653               0 :     for (nsView* v = aView->GetFirstChild(); v; v = v->GetNextSibling()) {
     654               0 :       if (v->GetZIndexIsAuto()) {
     655               0 :         UpdateNativeWidgetZIndexes(v, aZIndex);
     656                 :       }
     657                 :     }
     658                 :   }
     659               0 : }
     660                 : 
     661               0 : static PRInt32 FindNonAutoZIndex(nsView* aView)
     662                 : {
     663               0 :   while (aView) {
     664               0 :     if (!aView->GetZIndexIsAuto()) {
     665               0 :       return aView->GetZIndex();
     666                 :     }
     667               0 :     aView = aView->GetParent();
     668                 :   }
     669               0 :   return 0;
     670                 : }
     671                 : 
     672               0 : nsresult nsIView::CreateWidget(nsWidgetInitData *aWidgetInitData,
     673                 :                                bool aEnableDragDrop,
     674                 :                                bool aResetVisibility)
     675                 : {
     676                 :   return Impl()->CreateWidget(aWidgetInitData,
     677               0 :                               aEnableDragDrop, aResetVisibility);
     678                 : }
     679                 : 
     680               0 : nsresult nsIView::CreateWidgetForParent(nsIWidget* aParentWidget,
     681                 :                                         nsWidgetInitData *aWidgetInitData,
     682                 :                                         bool aEnableDragDrop,
     683                 :                                         bool aResetVisibility)
     684                 : {
     685                 :   return Impl()->CreateWidgetForParent(aParentWidget, aWidgetInitData,
     686               0 :                                        aEnableDragDrop, aResetVisibility);
     687                 : }
     688                 : 
     689               0 : nsresult nsIView::CreateWidgetForPopup(nsWidgetInitData *aWidgetInitData,
     690                 :                                        nsIWidget* aParentWidget,
     691                 :                                        bool aEnableDragDrop,
     692                 :                                        bool aResetVisibility)
     693                 : {
     694                 :   return Impl()->CreateWidgetForPopup(aWidgetInitData, aParentWidget,
     695               0 :                                       aEnableDragDrop, aResetVisibility);
     696                 : }
     697                 : 
     698               0 : void nsIView::DestroyWidget()
     699                 : {
     700               0 :   Impl()->DestroyWidget();
     701               0 : }
     702                 : 
     703                 : struct DefaultWidgetInitData : public nsWidgetInitData {
     704               0 :   DefaultWidgetInitData() : nsWidgetInitData()
     705                 :   {
     706               0 :     mWindowType = eWindowType_child;
     707               0 :     clipChildren = true;
     708               0 :     clipSiblings = true;
     709               0 :   }
     710                 : };
     711                 : 
     712               0 : nsresult nsView::CreateWidget(nsWidgetInitData *aWidgetInitData,
     713                 :                               bool aEnableDragDrop,
     714                 :                               bool aResetVisibility)
     715                 : {
     716               0 :   AssertNoWindow();
     717               0 :   NS_ABORT_IF_FALSE(!aWidgetInitData ||
     718                 :                     aWidgetInitData->mWindowType != eWindowType_popup,
     719                 :                     "Use CreateWidgetForPopup");
     720                 : 
     721               0 :   DefaultWidgetInitData defaultInitData;
     722               0 :   bool initDataPassedIn = !!aWidgetInitData;
     723               0 :   aWidgetInitData = aWidgetInitData ? aWidgetInitData : &defaultInitData;
     724                 :   defaultInitData.mListenForResizes =
     725               0 :     (!initDataPassedIn && GetParent() &&
     726               0 :      GetParent()->GetViewManager() != mViewManager);
     727                 : 
     728               0 :   nsIntRect trect = CalcWidgetBounds(aWidgetInitData->mWindowType);
     729                 : 
     730               0 :   nsRefPtr<nsDeviceContext> dx;
     731               0 :   mViewManager->GetDeviceContext(*getter_AddRefs(dx));
     732                 : 
     733                 :   nsIWidget* parentWidget =
     734               0 :     GetParent() ? GetParent()->GetNearestWidget(nsnull) : nsnull;
     735               0 :   if (!parentWidget) {
     736               0 :     NS_ERROR("nsView::CreateWidget without suitable parent widget??");
     737               0 :     return NS_ERROR_FAILURE;
     738                 :   }
     739                 : 
     740                 :   // XXX: using aForceUseIWidgetParent=true to preserve previous
     741                 :   // semantics.  It's not clear that it's actually needed.
     742                 :   mWindow = parentWidget->CreateChild(trect, ::HandleEvent,
     743                 :                                       dx, aWidgetInitData,
     744               0 :                                       true).get();
     745               0 :   if (!mWindow) {
     746               0 :     return NS_ERROR_FAILURE;
     747                 :   }
     748                 :  
     749               0 :   InitializeWindow(aEnableDragDrop, aResetVisibility);
     750                 : 
     751               0 :   return NS_OK;
     752                 : }
     753                 : 
     754               0 : nsresult nsView::CreateWidgetForParent(nsIWidget* aParentWidget,
     755                 :                                        nsWidgetInitData *aWidgetInitData,
     756                 :                                        bool aEnableDragDrop,
     757                 :                                        bool aResetVisibility)
     758                 : {
     759               0 :   AssertNoWindow();
     760               0 :   NS_ABORT_IF_FALSE(!aWidgetInitData ||
     761                 :                     aWidgetInitData->mWindowType != eWindowType_popup,
     762                 :                     "Use CreateWidgetForPopup");
     763               0 :   NS_ABORT_IF_FALSE(aParentWidget, "Parent widget required");
     764                 : 
     765               0 :   DefaultWidgetInitData defaultInitData;
     766               0 :   aWidgetInitData = aWidgetInitData ? aWidgetInitData : &defaultInitData;
     767                 : 
     768               0 :   nsIntRect trect = CalcWidgetBounds(aWidgetInitData->mWindowType);
     769                 : 
     770               0 :   nsRefPtr<nsDeviceContext> dx;
     771               0 :   mViewManager->GetDeviceContext(*getter_AddRefs(dx));
     772                 : 
     773                 :   mWindow =
     774                 :     aParentWidget->CreateChild(trect, ::HandleEvent,
     775               0 :                                dx, aWidgetInitData).get();
     776               0 :   if (!mWindow) {
     777               0 :     return NS_ERROR_FAILURE;
     778                 :   }
     779                 : 
     780               0 :   InitializeWindow(aEnableDragDrop, aResetVisibility);
     781                 : 
     782               0 :   return NS_OK;
     783                 : }
     784                 : 
     785               0 : nsresult nsView::CreateWidgetForPopup(nsWidgetInitData *aWidgetInitData,
     786                 :                                       nsIWidget* aParentWidget,
     787                 :                                       bool aEnableDragDrop,
     788                 :                                       bool aResetVisibility)
     789                 : {
     790               0 :   AssertNoWindow();
     791               0 :   NS_ABORT_IF_FALSE(aWidgetInitData, "Widget init data required");
     792               0 :   NS_ABORT_IF_FALSE(aWidgetInitData->mWindowType == eWindowType_popup,
     793                 :                     "Use one of the other CreateWidget methods");
     794                 : 
     795               0 :   nsIntRect trect = CalcWidgetBounds(aWidgetInitData->mWindowType);
     796                 : 
     797               0 :   nsRefPtr<nsDeviceContext> dx;
     798               0 :   mViewManager->GetDeviceContext(*getter_AddRefs(dx));
     799                 : 
     800                 :   // XXX/cjones: having these two separate creation cases seems ... um
     801                 :   // ... unnecessary, but it's the way the old code did it.  Please
     802                 :   // unify them by first finding a suitable parent nsIWidget, then
     803                 :   // getting rid of aForceUseIWidgetParent.
     804               0 :   if (aParentWidget) {
     805                 :     // XXX: using aForceUseIWidgetParent=true to preserve previous
     806                 :     // semantics.  It's not clear that it's actually needed.
     807                 :     mWindow = aParentWidget->CreateChild(trect, ::HandleEvent,
     808                 :                                          dx, aWidgetInitData,
     809               0 :                                          true).get();
     810                 :   }
     811                 :   else {
     812               0 :     nsIWidget* nearestParent = GetParent() ? GetParent()->GetNearestWidget(nsnull)
     813               0 :                                            : nsnull;
     814               0 :     if (!nearestParent) {
     815                 :       // Without a parent, we can't make a popup.  This can happen
     816                 :       // when printing
     817               0 :       return NS_ERROR_FAILURE;
     818                 :     }
     819                 : 
     820                 :     mWindow =
     821                 :       nearestParent->CreateChild(trect, ::HandleEvent,
     822               0 :                                  dx, aWidgetInitData).get();
     823                 :   }
     824               0 :   if (!mWindow) {
     825               0 :     return NS_ERROR_FAILURE;
     826                 :   }
     827                 : 
     828               0 :   InitializeWindow(aEnableDragDrop, aResetVisibility);
     829                 : 
     830               0 :   return NS_OK;
     831                 : }
     832                 : 
     833                 : void
     834               0 : nsView::InitializeWindow(bool aEnableDragDrop, bool aResetVisibility)
     835                 : {
     836               0 :   NS_ABORT_IF_FALSE(mWindow, "Must have a window to initialize");
     837                 : 
     838               0 :   ViewWrapper* wrapper = new ViewWrapper(this);
     839               0 :   NS_ADDREF(wrapper); // Will be released in ~nsView
     840               0 :   mWindow->SetClientData(wrapper);
     841                 : 
     842               0 :   if (aEnableDragDrop) {
     843               0 :     mWindow->EnableDragDrop(true);
     844                 :   }
     845                 :       
     846                 :   // propagate the z-index to the widget.
     847               0 :   UpdateNativeWidgetZIndexes(this, FindNonAutoZIndex(this));
     848                 : 
     849                 :   //make sure visibility state is accurate
     850                 : 
     851               0 :   if (aResetVisibility) {
     852               0 :     SetVisibility(GetVisibility());
     853                 :   }
     854               0 : }
     855                 : 
     856                 : // Attach to a top level widget and start receiving mirrored events.
     857               0 : nsresult nsIView::AttachToTopLevelWidget(nsIWidget* aWidget)
     858                 : {
     859               0 :   NS_PRECONDITION(nsnull != aWidget, "null widget ptr");
     860                 :   /// XXXjimm This is a temporary workaround to an issue w/document
     861                 :   // viewer (bug 513162).
     862               0 :   nsIView *oldView = GetAttachedViewFor(aWidget);
     863               0 :   if (oldView) {
     864               0 :     oldView->DetachFromTopLevelWidget();
     865                 :   }
     866                 : 
     867               0 :   nsRefPtr<nsDeviceContext> dx;
     868               0 :   mViewManager->GetDeviceContext(*getter_AddRefs(dx));
     869                 : 
     870                 :   // Note, the previous device context will be released. Detaching
     871                 :   // will not restore the old one.
     872                 :   nsresult rv = aWidget->AttachViewToTopLevel(
     873               0 :     nsIWidget::UsePuppetWidgets() ? ::HandleEvent : ::AttachedHandleEvent, dx);
     874               0 :   if (NS_FAILED(rv))
     875               0 :     return rv;
     876                 : 
     877               0 :   mWindow = aWidget;
     878               0 :   NS_ADDREF(mWindow);
     879                 : 
     880               0 :   ViewWrapper* wrapper = new ViewWrapper(Impl());
     881               0 :   NS_ADDREF(wrapper);
     882               0 :   mWindow->SetAttachedViewPtr(wrapper);
     883               0 :   mWindow->EnableDragDrop(true);
     884               0 :   mWidgetIsTopLevel = true;
     885                 : 
     886                 :   // Refresh the view bounds
     887                 :   nsWindowType type;
     888               0 :   mWindow->GetWindowType(type);
     889               0 :   CalcWidgetBounds(type);
     890                 : 
     891               0 :   return NS_OK;
     892                 : }
     893                 : 
     894                 : // Detach this view from an attached widget. 
     895               0 : nsresult nsIView::DetachFromTopLevelWidget()
     896                 : {
     897               0 :   NS_PRECONDITION(mWidgetIsTopLevel, "Not attached currently!");
     898               0 :   NS_PRECONDITION(mWindow, "null mWindow for DetachFromTopLevelWidget!");
     899                 : 
     900                 :   // Release memory for the view wrapper
     901               0 :   ViewWrapper* wrapper = GetAttachedWrapperFor(mWindow);
     902               0 :   NS_IF_RELEASE(wrapper);
     903                 : 
     904               0 :   mWindow->SetAttachedViewPtr(nsnull);
     905               0 :   NS_RELEASE(mWindow);
     906                 : 
     907               0 :   mWidgetIsTopLevel = false;
     908                 :   
     909               0 :   return NS_OK;
     910                 : }
     911                 : 
     912               0 : void nsView::SetZIndex(bool aAuto, PRInt32 aZIndex, bool aTopMost)
     913                 : {
     914               0 :   bool oldIsAuto = GetZIndexIsAuto();
     915               0 :   mVFlags = (mVFlags & ~NS_VIEW_FLAG_AUTO_ZINDEX) | (aAuto ? NS_VIEW_FLAG_AUTO_ZINDEX : 0);
     916               0 :   mZIndex = aZIndex;
     917               0 :   SetTopMost(aTopMost);
     918                 :   
     919               0 :   if (HasWidget() || !oldIsAuto || !aAuto) {
     920               0 :     UpdateNativeWidgetZIndexes(this, FindNonAutoZIndex(this));
     921                 :   }
     922               0 : }
     923                 : 
     924               0 : void nsView::AssertNoWindow()
     925                 : {
     926                 :   // XXX: it would be nice to make this a strong assert
     927               0 :   if (NS_UNLIKELY(mWindow)) {
     928               0 :     NS_ERROR("We already have a window for this view? BAD");
     929               0 :     ViewWrapper* wrapper = GetWrapperFor(mWindow);
     930               0 :     NS_IF_RELEASE(wrapper);
     931               0 :     mWindow->SetClientData(nsnull);
     932               0 :     mWindow->Destroy();
     933               0 :     NS_RELEASE(mWindow);
     934                 :   }
     935               0 : }
     936                 : 
     937                 : //
     938                 : // internal window creation functions
     939                 : //
     940               0 : EVENT_CALLBACK nsIView::AttachWidgetEventHandler(nsIWidget* aWidget)
     941                 : {
     942                 : #ifdef DEBUG
     943               0 :   void* data = nsnull;
     944               0 :   aWidget->GetClientData(data);
     945               0 :   NS_ASSERTION(!data, "Already got client data");
     946                 : #endif
     947                 : 
     948               0 :   ViewWrapper* wrapper = new ViewWrapper(Impl());
     949               0 :   if (!wrapper)
     950               0 :     return nsnull;
     951               0 :   NS_ADDREF(wrapper); // Will be released in DetachWidgetEventHandler
     952               0 :   aWidget->SetClientData(wrapper);
     953               0 :   return ::HandleEvent;
     954                 : }
     955                 : 
     956               0 : void nsIView::DetachWidgetEventHandler(nsIWidget* aWidget)
     957                 : {
     958               0 :   ViewWrapper* wrapper = GetWrapperFor(aWidget);
     959               0 :   NS_ASSERTION(!wrapper || wrapper->GetView() == this, "Wrong view");
     960               0 :   NS_IF_RELEASE(wrapper);
     961               0 :   aWidget->SetClientData(nsnull);
     962               0 : }
     963                 : 
     964                 : #ifdef DEBUG
     965               0 : void nsIView::List(FILE* out, PRInt32 aIndent) const
     966                 : {
     967                 :   PRInt32 i;
     968               0 :   for (i = aIndent; --i >= 0; ) fputs("  ", out);
     969               0 :   fprintf(out, "%p ", (void*)this);
     970               0 :   if (nsnull != mWindow) {
     971               0 :     nscoord p2a = mViewManager->AppUnitsPerDevPixel();
     972               0 :     nsIntRect rect;
     973               0 :     mWindow->GetClientBounds(rect);
     974               0 :     nsRect windowBounds = rect.ToAppUnits(p2a);
     975               0 :     mWindow->GetBounds(rect);
     976               0 :     nsRect nonclientBounds = rect.ToAppUnits(p2a);
     977               0 :     nsrefcnt widgetRefCnt = mWindow->AddRef() - 1;
     978               0 :     mWindow->Release();
     979                 :     PRInt32 Z;
     980               0 :     mWindow->GetZIndex(&Z);
     981                 :     fprintf(out, "(widget=%p[%d] z=%d pos={%d,%d,%d,%d}) ",
     982                 :             (void*)mWindow, widgetRefCnt, Z,
     983                 :             nonclientBounds.x, nonclientBounds.y,
     984               0 :             windowBounds.width, windowBounds.height);
     985                 :   }
     986               0 :   nsRect brect = GetBounds();
     987                 :   fprintf(out, "{%d,%d,%d,%d}",
     988               0 :           brect.x, brect.y, brect.width, brect.height);
     989                 :   fprintf(out, " z=%d vis=%d frame=%p <\n",
     990               0 :           mZIndex, mVis, mFrame);
     991               0 :   for (nsView* kid = mFirstChild; kid; kid = kid->GetNextSibling()) {
     992               0 :     NS_ASSERTION(kid->GetParent() == this, "incorrect parent");
     993               0 :     kid->List(out, aIndent + 1);
     994                 :   }
     995               0 :   for (i = aIndent; --i >= 0; ) fputs("  ", out);
     996               0 :   fputs(">\n", out);
     997               0 : }
     998                 : #endif // DEBUG
     999                 : 
    1000               0 : nsPoint nsIView::GetOffsetTo(const nsIView* aOther) const
    1001                 : {
    1002                 :   return Impl()->GetOffsetTo(static_cast<const nsView*>(aOther),
    1003               0 :                              Impl()->GetViewManager()->AppUnitsPerDevPixel());
    1004                 : }
    1005                 : 
    1006               0 : nsPoint nsView::GetOffsetTo(const nsView* aOther) const
    1007                 : {
    1008               0 :   return GetOffsetTo(aOther, GetViewManager()->AppUnitsPerDevPixel());
    1009                 : }
    1010                 : 
    1011               0 : nsPoint nsView::GetOffsetTo(const nsView* aOther, const PRInt32 aAPD) const
    1012                 : {
    1013               0 :   NS_ABORT_IF_FALSE(GetParent() || !aOther || aOther->GetParent() ||
    1014                 :                     this == aOther, "caller of (outer) GetOffsetTo must not "
    1015                 :                     "pass unrelated views");
    1016                 :   // We accumulate the final result in offset
    1017               0 :   nsPoint offset(0, 0);
    1018                 :   // The offset currently accumulated at the current APD
    1019               0 :   nsPoint docOffset(0, 0);
    1020               0 :   const nsView* v = this;
    1021               0 :   nsViewManager* currVM = v->GetViewManager();
    1022               0 :   PRInt32 currAPD = currVM->AppUnitsPerDevPixel();
    1023               0 :   const nsView* root = nsnull;
    1024               0 :   for ( ; v != aOther && v; root = v, v = v->GetParent()) {
    1025               0 :     nsViewManager* newVM = v->GetViewManager();
    1026               0 :     if (newVM != currVM) {
    1027               0 :       PRInt32 newAPD = newVM->AppUnitsPerDevPixel();
    1028               0 :       if (newAPD != currAPD) {
    1029               0 :         offset += docOffset.ConvertAppUnits(currAPD, aAPD);
    1030               0 :         docOffset.x = docOffset.y = 0;
    1031               0 :         currAPD = newAPD;
    1032                 :       }
    1033               0 :       currVM = newVM;
    1034                 :     }
    1035               0 :     docOffset += v->GetPosition();
    1036                 :   }
    1037               0 :   offset += docOffset.ConvertAppUnits(currAPD, aAPD);
    1038                 : 
    1039               0 :   if (v != aOther) {
    1040                 :     // Looks like aOther wasn't an ancestor of |this|.  So now we have
    1041                 :     // the root-VM-relative position of |this| in |offset|.  Get the
    1042                 :     // root-VM-relative position of aOther and subtract it.
    1043               0 :     nsPoint negOffset = aOther->GetOffsetTo(root, aAPD);
    1044               0 :     offset -= negOffset;
    1045                 :   }
    1046                 : 
    1047                 :   return offset;
    1048                 : }
    1049                 : 
    1050               0 : nsPoint nsIView::GetOffsetToWidget(nsIWidget* aWidget) const
    1051                 : {
    1052               0 :   nsPoint pt;
    1053                 :   // Get the view for widget
    1054               0 :   nsIView* widgetIView = GetViewFor(aWidget);
    1055               0 :   if (!widgetIView) {
    1056               0 :     return pt;
    1057                 :   }
    1058               0 :   nsView* widgetView = widgetIView->Impl();
    1059                 : 
    1060                 :   // Get the offset to the widget view in the widget view's APD
    1061                 :   // We get the offset in the widget view's APD first and then convert to our
    1062                 :   // APD afterwards so that we can include the widget view's ViewToWidgetOffset
    1063                 :   // in the sum in its native APD, and then convert the whole thing to our APD
    1064                 :   // so that we don't have to convert the APD of the relatively small
    1065                 :   // ViewToWidgetOffset by itself with a potentially large relative rounding
    1066                 :   // error.
    1067               0 :   pt = -widgetView->GetOffsetTo(static_cast<const nsView*>(this));
    1068                 :   // Add in the offset to the widget.
    1069               0 :   pt += widgetView->ViewToWidgetOffset();
    1070                 : 
    1071                 :   // Convert to our appunits.
    1072               0 :   PRInt32 widgetAPD = widgetView->GetViewManager()->AppUnitsPerDevPixel();
    1073                 :   PRInt32 ourAPD = static_cast<const nsView*>(this)->
    1074               0 :                     GetViewManager()->AppUnitsPerDevPixel();
    1075               0 :   pt = pt.ConvertAppUnits(widgetAPD, ourAPD);
    1076               0 :   return pt;
    1077                 : }
    1078                 : 
    1079               0 : nsIWidget* nsIView::GetNearestWidget(nsPoint* aOffset) const
    1080                 : {
    1081                 :   return Impl()->GetNearestWidget(aOffset,
    1082               0 :                                   Impl()->GetViewManager()->AppUnitsPerDevPixel());
    1083                 : }
    1084                 : 
    1085               0 : nsIWidget* nsView::GetNearestWidget(nsPoint* aOffset) const
    1086                 : {
    1087               0 :   return GetNearestWidget(aOffset, GetViewManager()->AppUnitsPerDevPixel());
    1088                 : }
    1089                 : 
    1090               0 : nsIWidget* nsView::GetNearestWidget(nsPoint* aOffset, const PRInt32 aAPD) const
    1091                 : {
    1092                 :   // aOffset is based on the view's position, which ignores any chrome on
    1093                 :   // attached parent widgets.
    1094                 : 
    1095                 :   // We accumulate the final result in pt
    1096               0 :   nsPoint pt(0, 0);
    1097                 :   // The offset currently accumulated at the current APD
    1098               0 :   nsPoint docPt(0,0);
    1099               0 :   const nsView* v = this;
    1100               0 :   nsViewManager* currVM = v->GetViewManager();
    1101               0 :   PRInt32 currAPD = currVM->AppUnitsPerDevPixel();
    1102               0 :   for ( ; v && !v->HasWidget(); v = v->GetParent()) {
    1103               0 :     nsViewManager* newVM = v->GetViewManager();
    1104               0 :     if (newVM != currVM) {
    1105               0 :       PRInt32 newAPD = newVM->AppUnitsPerDevPixel();
    1106               0 :       if (newAPD != currAPD) {
    1107               0 :         pt += docPt.ConvertAppUnits(currAPD, aAPD);
    1108               0 :         docPt.x = docPt.y = 0;
    1109               0 :         currAPD = newAPD;
    1110                 :       }
    1111               0 :       currVM = newVM;
    1112                 :     }
    1113               0 :     docPt += v->GetPosition();
    1114                 :   }
    1115               0 :   if (!v) {
    1116               0 :     if (aOffset) {
    1117               0 :       pt += docPt.ConvertAppUnits(currAPD, aAPD);
    1118               0 :       *aOffset = pt;
    1119                 :     }
    1120               0 :     return nsnull;
    1121                 :   }
    1122                 : 
    1123                 :   // pt is now the offset from v's origin to this view's origin.
    1124                 :   // We add the ViewToWidgetOffset to get the offset to the widget.
    1125               0 :   if (aOffset) {
    1126               0 :     docPt += v->ViewToWidgetOffset();
    1127               0 :     pt += docPt.ConvertAppUnits(currAPD, aAPD);
    1128               0 :     *aOffset = pt;
    1129                 :   }
    1130               0 :   return v->GetWidget();
    1131                 : }
    1132                 : 
    1133               0 : bool nsIView::IsRoot() const
    1134                 : {
    1135               0 :   NS_ASSERTION(mViewManager != nsnull," View manager is null in nsView::IsRoot()");
    1136               0 :   return mViewManager->GetRootViewImpl() == this;
    1137                 : }
    1138                 : 
    1139               0 : bool nsIView::ExternalIsRoot() const
    1140                 : {
    1141               0 :   return nsIView::IsRoot();
    1142                 : }
    1143                 : 
    1144                 : void
    1145               0 : nsIView::SetDeletionObserver(nsWeakView* aDeletionObserver)
    1146                 : {
    1147               0 :   if (mDeletionObserver && aDeletionObserver) {
    1148               0 :     aDeletionObserver->SetPrevious(mDeletionObserver);
    1149                 :   }
    1150               0 :   mDeletionObserver = aDeletionObserver;
    1151               0 : }
    1152                 : 
    1153                 : nsView*
    1154               0 : nsIView::Impl()
    1155                 : {
    1156               0 :   return static_cast<nsView*>(this);
    1157                 : }
    1158                 : 
    1159                 : const nsView*
    1160               0 : nsIView::Impl() const
    1161                 : {
    1162               0 :   return static_cast<const nsView*>(this);
    1163                 : }
    1164                 : 
    1165                 : nsRect
    1166               0 : nsView::GetBoundsInParentUnits() const
    1167                 : {
    1168               0 :   nsView* parent = GetParent();
    1169               0 :   nsViewManager* VM = GetViewManager();
    1170               0 :   if (this != VM->GetRootViewImpl() || !parent) {
    1171               0 :     return mDimBounds;
    1172                 :   }
    1173               0 :   PRInt32 ourAPD = VM->AppUnitsPerDevPixel();
    1174               0 :   PRInt32 parentAPD = parent->GetViewManager()->AppUnitsPerDevPixel();
    1175               0 :   return mDimBounds.ConvertAppUnitsRoundOut(ourAPD, parentAPD);
    1176                 : }
    1177                 : 
    1178                 : nsPoint
    1179               0 : nsIView::ConvertFromParentCoords(nsPoint aPt) const
    1180                 : {
    1181               0 :   const nsView* view = static_cast<const nsView*>(this);
    1182               0 :   const nsView* parent = view->GetParent();
    1183               0 :   if (parent) {
    1184               0 :     aPt = aPt.ConvertAppUnits(parent->GetViewManager()->AppUnitsPerDevPixel(),
    1185               0 :                               view->GetViewManager()->AppUnitsPerDevPixel());
    1186                 :   }
    1187               0 :   aPt -= GetPosition();
    1188               0 :   return aPt;
    1189                 : }

Generated by: LCOV version 1.7