From c956c22a62fc4b9d318f527486ae8f3315aab687 Mon Sep 17 00:00:00 2001 From: "beard%netscape.com" Date: Tue, 25 Jan 2000 01:53:34 +0000 Subject: [PATCH] floating views. bug=21966, r=troy, rods, a=brendan git-svn-id: svn://10.0.0.236/trunk@58504 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/forms/nsListControlFrame.cpp | 4 +- .../html/forms/src/nsListControlFrame.cpp | 4 +- .../layout/xul/base/src/nsMenuPopupFrame.cpp | 5 + mozilla/view/public/nsIView.h | 13 + mozilla/view/src/nsScrollPortView.cpp | 14 + mozilla/view/src/nsView.cpp | 826 +++++++++--------- mozilla/view/src/nsView.h | 2 + mozilla/view/src/nsViewManager.cpp | 19 +- mozilla/view/src/nsViewManager2.cpp | 498 ++++++----- 9 files changed, 705 insertions(+), 680 deletions(-) diff --git a/mozilla/layout/forms/nsListControlFrame.cpp b/mozilla/layout/forms/nsListControlFrame.cpp index 1f4e13abe8f..b1bbf4b16ad 100644 --- a/mozilla/layout/forms/nsListControlFrame.cpp +++ b/mozilla/layout/forms/nsListControlFrame.cpp @@ -2181,11 +2181,11 @@ nsListControlFrame::CreateScrollingViewWidget(nsIView* aView, const nsStylePosit { if (IsInDropDownMode() == PR_TRUE) { nsWidgetInitData widgetData; - aView->SetZIndex(kMaxZ); + // aView->SetZIndex(kMaxZ); + aView->SetFloating(PR_TRUE); widgetData.mWindowType = eWindowType_popup; widgetData.mBorderStyle = eBorderStyle_default; - #ifdef XP_MAC static NS_DEFINE_IID(kCPopUpCID, NS_POPUP_CID); aView->CreateWidget(kCPopUpCID, &widgetData, nsnull); diff --git a/mozilla/layout/html/forms/src/nsListControlFrame.cpp b/mozilla/layout/html/forms/src/nsListControlFrame.cpp index 1f4e13abe8f..b1bbf4b16ad 100644 --- a/mozilla/layout/html/forms/src/nsListControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsListControlFrame.cpp @@ -2181,11 +2181,11 @@ nsListControlFrame::CreateScrollingViewWidget(nsIView* aView, const nsStylePosit { if (IsInDropDownMode() == PR_TRUE) { nsWidgetInitData widgetData; - aView->SetZIndex(kMaxZ); + // aView->SetZIndex(kMaxZ); + aView->SetFloating(PR_TRUE); widgetData.mWindowType = eWindowType_popup; widgetData.mBorderStyle = eBorderStyle_default; - #ifdef XP_MAC static NS_DEFINE_IID(kCPopUpCID, NS_POPUP_CID); aView->CreateWidget(kCPopUpCID, &widgetData, nsnull); diff --git a/mozilla/layout/xul/base/src/nsMenuPopupFrame.cpp b/mozilla/layout/xul/base/src/nsMenuPopupFrame.cpp index 94942ec515c..3b472e290d2 100644 --- a/mozilla/layout/xul/base/src/nsMenuPopupFrame.cpp +++ b/mozilla/layout/xul/base/src/nsMenuPopupFrame.cpp @@ -148,6 +148,11 @@ nsMenuPopupFrame::Init(nsIPresContext* aPresContext, viewManager->GetRootView(rootView); viewManager->InsertChild(rootView, ourView, kMaxZ); + // XXX Hack. The menu's view should float above all other views, + // so we use the nsIView::SetFloating() to tell the view manager + // about that constraint. + ourView->SetFloating(PR_TRUE); + // XXX Hack. Change our transparency to be non-transparent // until the bug related to update of transparency on show/hide // is fixed. diff --git a/mozilla/view/public/nsIView.h b/mozilla/view/public/nsIView.h index 5ec12215749..c16074e9700 100644 --- a/mozilla/view/public/nsIView.h +++ b/mozilla/view/public/nsIView.h @@ -263,6 +263,17 @@ public: */ NS_IMETHOD GetAutoZIndex(PRBool &aAutoZIndex) const = 0; + /** + * Set/Get whether the view "floats" above all other views, + * which tells the compositor not to consider higher views in + * the view hierarchy that would geometrically intersect with + * this view. This is a hack, but it fixes some problems with + * views that need to be drawn in front of all other views. + * @result PR_TRUE if the view floats, PR_FALSE otherwise. + */ + NS_IMETHOD SetFloating(PRBool aFloatingView) = 0; + NS_IMETHOD GetFloating(PRBool &aFloatingView) const = 0; + /** * Called to set the parent of the view. * @param aParent new parent @@ -539,5 +550,7 @@ private: #define NS_VIEW_PUBLIC_FLAG_DONT_BITBLT 0x0010 // indicates that the view is using auto z-indexing #define NS_VIEW_PUBLIC_FLAG_AUTO_ZINDEX 0x0020 +// indicatest hat the view is a floating view. +#define NS_VIEW_PUBLIC_FLAG_FLOATING 0x0040 #endif diff --git a/mozilla/view/src/nsScrollPortView.cpp b/mozilla/view/src/nsScrollPortView.cpp index 6cbc13069da..7d26ccbb780 100644 --- a/mozilla/view/src/nsScrollPortView.cpp +++ b/mozilla/view/src/nsScrollPortView.cpp @@ -72,6 +72,11 @@ nsresult nsScrollPortView::QueryInterface(const nsIID& aIID, void** aInstancePtr return NS_OK; } + if (aIID.Equals(NS_GET_IID(nsIClipView))) { + *aInstancePtr = (void*)(nsIClipView*)this; + return NS_OK; + } + return nsView::QueryInterface(aIID, aInstancePtr); } @@ -531,6 +536,15 @@ void nsScrollPortView::Scroll(nsIView *aScrolledView, PRInt32 aDx, PRInt32 aDy, NS_IMETHODIMP nsScrollPortView::Paint(nsIRenderingContext& rc, const nsRect& rect, PRUint32 aPaintFlags, PRBool &aResult) { + PRBool clipEmpty; + rc.PushState(); + nsRect bounds = mBounds; + bounds.x = bounds.y = 0; + rc.SetClipRect(bounds, nsClipCombine_kIntersect, clipEmpty); + nsresult rv = nsView::Paint(rc, rect, aPaintFlags, aResult); + + rc.PopState(clipEmpty); + return rv; } diff --git a/mozilla/view/src/nsView.cpp b/mozilla/view/src/nsView.cpp index 0e7c26210f5..ebc5d2053fb 100644 --- a/mozilla/view/src/nsView.cpp +++ b/mozilla/view/src/nsView.cpp @@ -267,495 +267,451 @@ NS_IMETHODIMP nsView :: GetViewManager(nsIViewManager *&aViewMgr) const NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect, PRUint32 aPaintFlags, PRBool &aResult) { - if (aPaintFlags & NS_VIEW_FLAG_JUST_PAINT) - { - //new compositor - - if (nsnull != mClientData) - { - nsIViewObserver *obs; - - if (NS_OK == mViewManager->GetViewObserver(obs)) - { - if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom)) - { - nsRect crect; - - crect.x = mClip.mLeft; - crect.y = mClip.mTop; - crect.width = mClip.mRight - mClip.mLeft; - crect.height = mClip.mBottom - mClip.mTop; - - rc.SetClipRect(crect, nsClipCombine_kIntersect, aResult); - } - - obs->Paint((nsIView *)this, rc, rect); - NS_RELEASE(obs); - } - } - } - else - { - nsIView *pRoot; - PRBool clipres = PR_FALSE; - PRBool clipwasset = PR_FALSE; - float opacity; - - mViewManager->GetRootView(pRoot); - - rc.PushState(); - - GetOpacity(opacity); - - if (aPaintFlags & NS_VIEW_FLAG_CLIP_SET) - { - clipwasset = PR_TRUE; - aPaintFlags &= ~NS_VIEW_FLAG_CLIP_SET; - } - else if (mVis == nsViewVisibility_kShow) - { - if (opacity == 1.0f) - { - nsRect brect; - - GetBounds(brect); - - if ((mClip.mLeft == mClip.mRight) || (mClip.mTop == mClip.mBottom) && - (this != pRoot)) - { - rc.SetClipRect(brect, nsClipCombine_kIntersect, clipres); - } - } - } - - if (clipres == PR_FALSE) - { - nscoord posx, posy; - - if (nsnull == mWindow) - { - GetPosition(&posx, &posy); - rc.Translate(posx, posy); - } - - if (nsnull != mXForm) - { - nsTransform2D *pXForm; - rc.GetCurrentTransform(pXForm); - pXForm->Concatenate(mXForm); - } - - //if we are not doing a two pass render, - //render the kids... - - if (!(aPaintFlags & (NS_VIEW_FLAG_FRONT_TO_BACK | NS_VIEW_FLAG_BACK_TO_FRONT))) - { - PRInt32 numkids; - - GetChildCount(numkids); - - for (PRInt32 cnt = 0; cnt < numkids; cnt++) - { - nsIView *kid; - - GetChild(cnt, kid); - - if (nsnull != kid) - { - // Don't paint child views that have widgets. They'll get their own - // native paint requests - nsIWidget *widget; - PRBool hasWidget; - - kid->GetWidget(widget); - hasWidget = (widget != nsnull); - if (nsnull != widget) - { - void *thing; - thing = widget->GetNativeData(NS_NATIVE_WIDGET); - NS_RELEASE(widget); - - if (nsnull == thing) - hasWidget = PR_FALSE; - } - if (!hasWidget) - { - nsRect kidRect; - kid->GetBounds(kidRect); - nsRect damageArea; - PRBool overlap = damageArea.IntersectRect(rect, kidRect); - - if (overlap == PR_TRUE) - { - // Translate damage area into kid's coordinate system - nsRect kidDamageArea(damageArea.x - kidRect.x, damageArea.y - kidRect.y, - damageArea.width, damageArea.height); - kid->Paint(rc, kidDamageArea, aPaintFlags, clipres); - - if (clipres == PR_TRUE) - break; - } - } - } - } - } - - if ((clipres == PR_FALSE) && (mVis == nsViewVisibility_kShow)) - { - //don't render things that can't be seen... - - if ((opacity > 0.0f) && (mBounds.width > 1) && (mBounds.height > 1)) - { - nsIRenderingContext *localcx = nsnull; - nsDrawingSurface surf = nsnull; - nsDrawingSurface redsurf = nsnull; - PRBool hasTransparency; - PRBool clipState; //for when we want to throw away the clip state - - rc.PushState(); - - HasTransparency(hasTransparency); - - if (opacity < 1.0f) - { - nsIDeviceContext *dx = nsnull; - nsIView *rootview = nsnull; - - //create offscreen bitmap to render view into - - mViewManager->GetDeviceContext(dx); - mViewManager->GetRootView(rootview); - - if ((nsnull != dx) && (nsnull != rootview)) - { - dx->CreateRenderingContext(rootview, localcx); - - if (nsnull != localcx) - { - float t2p; - nscoord width, height; - - //create offscreen buffer for blending... - - dx->GetAppUnitsToDevUnits(t2p); - - width = NSToCoordRound(mBounds.width * t2p); - height = NSToCoordRound(mBounds.height * t2p); - - nsRect bitrect = nsRect(0, 0, width, height); - - localcx->CreateDrawingSurface(&bitrect, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, surf); - localcx->CreateDrawingSurface(&bitrect, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, redsurf); - - if (nsnull != surf) - localcx->SelectOffScreenDrawingSurface(surf); - } - - NS_RELEASE(dx); - } - } - - if (nsnull == localcx) - localcx = &rc; - - if (hasTransparency || (opacity < 1.0f)) - { - //overview of algorithm: - //1. clip is set to intersection of this view and whatever is - // left of the damage region in the rc. - //2. walk tree from this point down through the view list, - // rendering and clipping out opaque views encountered until - // there is nothing left in the clip area or the bottommost - // view is reached. - //3. walk back up through view list restoring clips and painting - // or blending any non-opaque views encountered until we reach the - // view that started the whole process - - //walk down rendering only views within this clip - //clip is already set to this view in rendering context... - - nsIView *curview, *preview = this; - nsVoidArray *views = (nsVoidArray *)new nsVoidArray(); - nsVoidArray *rects = (nsVoidArray *)new nsVoidArray(); - // nscoord posx, posy; - nsRect damRect = rect; - - localcx->PushState(); - - GetPosition(&posx, &posy); - - //we need to go back to the coordinate system that was there - //before we came along... XXX xform not accounted for. MMP - damRect.x += posx; - damRect.y += posy; + if (aPaintFlags & NS_VIEW_FLAG_JUST_PAINT) + { + //new compositor + + if (nsnull != mClientData) { + nsCOMPtr observer; + if (NS_OK == mViewManager->GetViewObserver(*getter_AddRefs(observer))) { + if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom)) { + nsRect crect; + crect.x = mClip.mLeft; + crect.y = mClip.mTop; + crect.width = mClip.mRight - mClip.mLeft; + crect.height = mClip.mBottom - mClip.mTop; + rc.SetClipRect(crect, nsClipCombine_kIntersect, aResult); + } + observer->Paint((nsIView *)this, rc, rect); + } + } + } else { + nsIView *pRoot; + PRBool clipres = PR_FALSE; + PRBool clipwasset = PR_FALSE; + float opacity; + + mViewManager->GetRootView(pRoot); + + rc.PushState(); + + GetOpacity(opacity); + + if (aPaintFlags & NS_VIEW_FLAG_CLIP_SET) + { + clipwasset = PR_TRUE; + aPaintFlags &= ~NS_VIEW_FLAG_CLIP_SET; + } else if (mVis == nsViewVisibility_kShow) { + if (opacity == 1.0f) + { + nsRect brect; + GetBounds(brect); + + // what does this test mean? + if ((mClip.mLeft == mClip.mRight) || (mClip.mTop == mClip.mBottom) && (this != pRoot)) { + rc.SetClipRect(brect, nsClipCombine_kIntersect, clipres); + } + } + } + + if (clipres == PR_FALSE) + { + nscoord posx, posy; + + if (nsnull == mWindow) + { + GetPosition(&posx, &posy); + rc.Translate(posx, posy); + } + + if (nsnull != mXForm) + { + nsTransform2D *pXForm; + rc.GetCurrentTransform(pXForm); + pXForm->Concatenate(mXForm); + } + + //if we are not doing a two pass render, + //render the kids... + + if (!(aPaintFlags & (NS_VIEW_FLAG_FRONT_TO_BACK | NS_VIEW_FLAG_BACK_TO_FRONT))) { + PRInt32 numkids; + GetChildCount(numkids); + for (PRInt32 cnt = 0; cnt < numkids; cnt++) { + nsIView *kid; + GetChild(cnt, kid); + if (nsnull != kid) { + // Don't paint child views that have widgets. They'll get their own + // native paint requests + nsIWidget *widget; + PRBool hasWidget; + + kid->GetWidget(widget); + hasWidget = (widget != nsnull); + if (nsnull != widget) { + void *thing; + thing = widget->GetNativeData(NS_NATIVE_WIDGET); + NS_RELEASE(widget); + + if (nsnull == thing) + hasWidget = PR_FALSE; + } + if (!hasWidget) { + nsRect kidRect; + kid->GetBounds(kidRect); + nsRect damageArea; + PRBool overlap = damageArea.IntersectRect(rect, kidRect); + + if (overlap == PR_TRUE) { + // Translate damage area into kid's coordinate system + nsRect kidDamageArea(damageArea.x - kidRect.x, damageArea.y - kidRect.y, + damageArea.width, damageArea.height); + kid->Paint(rc, kidDamageArea, aPaintFlags, clipres); + + if (clipres == PR_TRUE) + break; + } + } + } + } + } + + if ((clipres == PR_FALSE) && (mVis == nsViewVisibility_kShow)) { + //don't render things that can't be seen... + + if ((opacity > 0.0f) && (mBounds.width > 1) && (mBounds.height > 1)) { + nsCOMPtr localcx; + nsDrawingSurface surf = nsnull; + nsDrawingSurface redsurf = nsnull; + PRBool hasTransparency; + PRBool clipState; //for when we want to throw away the clip state + + rc.PushState(); + + HasTransparency(hasTransparency); + + if (opacity < 1.0f) + { + nsIDeviceContext *dx = nsnull; + nsIView *rootview = nsnull; + + //create offscreen bitmap to render view into + + mViewManager->GetDeviceContext(dx); + mViewManager->GetRootView(rootview); + + if ((nsnull != dx) && (nsnull != rootview)) + { + dx->CreateRenderingContext(rootview, *getter_AddRefs(localcx)); + + if (nsnull != localcx) { + float t2p; + nscoord width, height; + + //create offscreen buffer for blending... + + dx->GetAppUnitsToDevUnits(t2p); + + width = NSToCoordRound(mBounds.width * t2p); + height = NSToCoordRound(mBounds.height * t2p); + + nsRect bitrect = nsRect(0, 0, width, height); + + localcx->CreateDrawingSurface(&bitrect, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, surf); + localcx->CreateDrawingSurface(&bitrect, NS_CREATEDRAWINGSURFACE_FOR_PIXEL_ACCESS, redsurf); + + if (nsnull != surf) + localcx->SelectOffScreenDrawingSurface(surf); + } + + NS_RELEASE(dx); + } + } - localcx->Translate(-posx, -posy); + if (nsnull == localcx) + localcx = &rc; - GetNextSibling(curview); + if (hasTransparency || (opacity < 1.0f)) { + //overview of algorithm: + //1. clip is set to intersection of this view and whatever is + // left of the damage region in the rc. + //2. walk tree from this point down through the view list, + // rendering and clipping out opaque views encountered until + // there is nothing left in the clip area or the bottommost + // view is reached. + //3. walk back up through view list restoring clips and painting + // or blending any non-opaque views encountered until we reach the + // view that started the whole process - if (nsnull == curview) - { - preview->GetParent(curview); + //walk down rendering only views within this clip + //clip is already set to this view in rendering context... - if (nsnull != curview) - { - nsRect prect; + nsIView *curview, *preview = this; + nsVoidArray *views = (nsVoidArray *)new nsVoidArray(); + nsVoidArray *rects = (nsVoidArray *)new nsVoidArray(); + // nscoord posx, posy; + nsRect damRect = rect; - curview->GetBounds(prect); + localcx->PushState(); - damRect.x += prect.x; - damRect.y += prect.y; + GetPosition(&posx, &posy); - localcx->Translate(-prect.x, -prect.y); - } - } + //we need to go back to the coordinate system that was there + //before we came along... XXX xform not accounted for. MMP + damRect.x += posx; + damRect.y += posy; - while (nsnull != curview) - { - nsRect kidRect; - curview->GetBounds(kidRect); - nsRect damageArea; - PRBool overlap = damageArea.IntersectRect(damRect, kidRect); + localcx->Translate(-posx, -posy); - if (overlap == PR_TRUE) - { - // Translate damage area into kid's coordinate system - // nsRect kidDamageArea(damageArea.x - kidRect.x, damageArea.y - kidRect.y, - // damageArea.width, damageArea.height); - nsRect kidDamageArea(damRect.x - kidRect.x, damRect.y - kidRect.y, - damRect.width, damRect.height); + GetNextSibling(curview); - //we will pop the states on the back to front pass... - localcx->PushState(); + if (nsnull == curview) + { + preview->GetParent(curview); - if (nsnull != views) - views->AppendElement(curview); + if (nsnull != curview) + { + nsRect prect; - rects->AppendElement(new nsRect(kidDamageArea)); + curview->GetBounds(prect); - curview->Paint(*localcx, kidDamageArea, aPaintFlags | NS_VIEW_FLAG_FRONT_TO_BACK, clipres); - } + damRect.x += prect.x; + damRect.y += prect.y; - if (clipres == PR_TRUE) - break; + localcx->Translate(-prect.x, -prect.y); + } + } - preview = curview; + while (nsnull != curview) + { + nsRect kidRect; + curview->GetBounds(kidRect); + nsRect damageArea; + PRBool overlap = damageArea.IntersectRect(damRect, kidRect); - curview->GetNextSibling(curview); + if (overlap == PR_TRUE) + { + // Translate damage area into kid's coordinate system + // nsRect kidDamageArea(damageArea.x - kidRect.x, damageArea.y - kidRect.y, + // damageArea.width, damageArea.height); + nsRect kidDamageArea(damRect.x - kidRect.x, damRect.y - kidRect.y, + damRect.width, damRect.height); - if (nsnull == curview) - { - preview->GetParent(curview); + //we will pop the states on the back to front pass... + localcx->PushState(); - if (nsnull != curview) - { - nsRect prect; + if (nsnull != views) + views->AppendElement(curview); - curview->GetBounds(prect); + rects->AppendElement(new nsRect(kidDamageArea)); - damRect.x += prect.x; - damRect.y += prect.y; + curview->Paint(*localcx, kidDamageArea, aPaintFlags | NS_VIEW_FLAG_FRONT_TO_BACK, clipres); + } - localcx->Translate(-prect.x, -prect.y); - } - } - } + if (clipres == PR_TRUE) + break; - //walk backwards, rendering views + preview = curview; - if (nsnull != views) - { - PRInt32 idx = views->Count(); - PRBool isfirst = PR_TRUE; + curview->GetNextSibling(curview); - while (idx > 0) - { - if (PR_TRUE == isfirst) - { - //we just rendered the last view at the - //end of the first pass, so there is no need - //to do so again. + if (nsnull == curview) + { + preview->GetParent(curview); - nsRect *trect = (nsRect *)rects->ElementAt(--idx); - delete trect; + if (nsnull != curview) + { + nsRect prect; - localcx->PopState(clipState); - isfirst = PR_FALSE; - } - else - { - curview = (nsIView *)views->ElementAt(--idx); - nsRect *trect = (nsRect *)rects->ElementAt(idx); + curview->GetBounds(prect); - curview->Paint(*localcx, *trect, aPaintFlags | NS_VIEW_FLAG_BACK_TO_FRONT, clipres); + damRect.x += prect.x; + damRect.y += prect.y; - delete trect; + localcx->Translate(-prect.x, -prect.y); + } + } + } - //pop the state pushed on the front to back pass... - localcx->PopState(clipState); - } - } + //walk backwards, rendering views - delete rects; - delete views; - } + if (nsnull != views) { + PRInt32 idx = views->Count(); + PRBool isfirst = PR_TRUE; - localcx->PopState(clipState); - } + while (idx > 0) { + if (PR_TRUE == isfirst) { + //we just rendered the last view at the + //end of the first pass, so there is no need + //to do so again. - if (nsnull != redsurf) - localcx->SelectOffScreenDrawingSurface(redsurf); + nsRect *trect = (nsRect *)rects->ElementAt(--idx); + delete trect; - //now draw ourself... + localcx->PopState(clipState); + isfirst = PR_FALSE; + } else { + curview = (nsIView *)views->ElementAt(--idx); + nsRect *trect = (nsRect *)rects->ElementAt(idx); - if (nsnull != mClientData) - { - nsIViewObserver *obs; + curview->Paint(*localcx, *trect, aPaintFlags | NS_VIEW_FLAG_BACK_TO_FRONT, clipres); - if (NS_OK == mViewManager->GetViewObserver(obs)) - { - if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom)) - { - nsRect crect, brect; + delete trect; - GetBounds(brect); + //pop the state pushed on the front to back pass... + localcx->PopState(clipState); + } + } - crect.x = mClip.mLeft + brect.x; - crect.y = mClip.mTop + brect.y; - crect.width = mClip.mRight - mClip.mLeft; - crect.height = mClip.mBottom - mClip.mTop; + delete rects; + delete views; + } - localcx->SetClipRect(crect, nsClipCombine_kIntersect, clipres); - } + localcx->PopState(clipState); + } - obs->Paint((nsIView *)this, *localcx, rect); - NS_RELEASE(obs); - } - } + if (nsnull != redsurf) + localcx->SelectOffScreenDrawingSurface(redsurf); - if (localcx != &rc) - { - // localcx->SelectOffScreenDrawingSurface(nsnull); - NS_RELEASE(localcx); - } - else - localcx = nsnull; + //now draw ourself... - //kill offscreen buffer + if (nsnull != mClientData) { + nsCOMPtr observer; + if (NS_OK == mViewManager->GetViewObserver(*getter_AddRefs(observer))) { + if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom)) { + nsRect crect(mClip.mLeft, mClip.mTop, + mClip.mRight - mClip.mLeft, + mClip.mBottom - mClip.mTop); + localcx->SetClipRect(crect, nsClipCombine_kIntersect, clipres); + } + observer->Paint((nsIView *)this, *localcx, rect); + } + } - if ((nsnull != surf) && (nsnull != redsurf)) - { - nsRect brect; +#if 1 + // release whatever hold we had on the context. + localcx = nsnull; +#else + if (localcx != &rc) { + // localcx->SelectOffScreenDrawingSurface(nsnull); + NS_RELEASE(localcx); + } else + localcx = nsnull; +#endif - brect.x = brect.y = 0; - brect.width = mBounds.width; - brect.height = mBounds.height; + //kill offscreen buffer - static NS_DEFINE_IID(kBlenderCID, NS_BLENDER_CID); - static NS_DEFINE_IID(kIBlenderIID, NS_IBLENDER_IID); + if ((nsnull != surf) && (nsnull != redsurf)) + { + nsRect brect; - nsIBlender *blender = nsnull; - nsresult rv; + brect.x = brect.y = 0; + brect.width = mBounds.width; + brect.height = mBounds.height; - rv = nsComponentManager::CreateInstance(kBlenderCID, nsnull, kIBlenderIID, (void **)&blender); + static NS_DEFINE_IID(kBlenderCID, NS_BLENDER_CID); + static NS_DEFINE_IID(kIBlenderIID, NS_IBLENDER_IID); - if (NS_OK == rv) - { - nsIDeviceContext *dx; + nsIBlender *blender = nsnull; + nsresult rv; - mViewManager->GetDeviceContext(dx); + rv = nsComponentManager::CreateInstance(kBlenderCID, nsnull, kIBlenderIID, (void **)&blender); - float t2p; - nscoord width, height; + if (NS_OK == rv) + { + nsIDeviceContext *dx; - dx->GetAppUnitsToDevUnits(t2p); + mViewManager->GetDeviceContext(dx); - width = NSToCoordRound(mBounds.width * t2p); - height = NSToCoordRound(mBounds.height * t2p); + float t2p; + nscoord width, height; - blender->Init(dx); - blender->Blend(0, 0, width, height,redsurf,surf, 0, 0, opacity); + dx->GetAppUnitsToDevUnits(t2p); - NS_RELEASE(blender); - NS_RELEASE(dx); + width = NSToCoordRound(mBounds.width * t2p); + height = NSToCoordRound(mBounds.height * t2p); - rc.CopyOffScreenBits(surf, 0, 0, brect, NS_COPYBITS_XFORM_DEST_VALUES); - } + blender->Init(dx); + blender->Blend(0, 0, width, height,redsurf,surf, 0, 0, opacity); - rc.DestroyDrawingSurface(surf); - rc.DestroyDrawingSurface(redsurf); + NS_RELEASE(blender); + NS_RELEASE(dx); + + rc.CopyOffScreenBits(surf, 0, 0, brect, NS_COPYBITS_XFORM_DEST_VALUES); + } + + rc.DestroyDrawingSurface(surf); + rc.DestroyDrawingSurface(redsurf); - surf = nsnull; - redsurf = nsnull; - } + surf = nsnull; + redsurf = nsnull; + } - #ifdef SHOW_VIEW_BORDERS - { - nscoord x, y, w, h; + #ifdef SHOW_VIEW_BORDERS + { + nscoord x, y, w, h; - if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom)) - { - x = mClip.mLeft; - y = mClip.mTop; - w = mClip.mRight - mClip.mLeft; - h = mClip.mBottom - mClip.mTop; + if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom)) + { + x = mClip.mLeft; + y = mClip.mTop; + w = mClip.mRight - mClip.mLeft; + h = mClip.mBottom - mClip.mTop; - rc.SetColor(NS_RGB(255, 255, 0)); - } - else - { - x = y = 0; + rc.SetColor(NS_RGB(255, 255, 0)); + } + else + { + x = y = 0; + + GetDimensions(&w, &h); - GetDimensions(&w, &h); + if (nsnull != mWindow) + rc.SetColor(NS_RGB(0, 255, 0)); + else + rc.SetColor(NS_RGB(0, 0, 255)); + } + + rc.DrawRect(x, y, w, h); + } + #endif + + rc.PopState(clipState); + } + } + } + + rc.PopState(clipres); - if (nsnull != mWindow) - rc.SetColor(NS_RGB(0, 255, 0)); - else - rc.SetColor(NS_RGB(0, 0, 255)); - } + //now we need to exclude this view from the rest of the + //paint process. only do this if this view is actually + //visible and if there is no widget (like a scrollbar) here. - rc.DrawRect(x, y, w, h); - } - #endif + if (!clipwasset && (clipres == PR_FALSE) && + (mVis == nsViewVisibility_kShow) && (nsnull == mWindow) && + (opacity > 0.0f)) + { + nsRect brect; + GetBounds(brect); - rc.PopState(clipState); - } - } - } + if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom)) + { + nsRect crect; - rc.PopState(clipres); + crect.x = mClip.mLeft + brect.x; + crect.y = mClip.mTop + brect.y; + crect.width = mClip.mRight - mClip.mLeft; + crect.height = mClip.mBottom - mClip.mTop; - //now we need to exclude this view from the rest of the - //paint process. only do this if this view is actually - //visible and if there is no widget (like a scrollbar) here. + rc.SetClipRect(crect, nsClipCombine_kSubtract, clipres); + } else if (this != pRoot) + rc.SetClipRect(brect, nsClipCombine_kSubtract, clipres); + } - if (!clipwasset && (clipres == PR_FALSE) && - (mVis == nsViewVisibility_kShow) && (nsnull == mWindow) && - (opacity > 0.0f)) - { - nsRect brect; + aResult = clipres; + } - GetBounds(brect); - - if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom)) - { - nsRect crect; - - crect.x = mClip.mLeft + brect.x; - crect.y = mClip.mTop + brect.y; - crect.width = mClip.mRight - mClip.mLeft; - crect.height = mClip.mBottom - mClip.mTop; - - rc.SetClipRect(crect, nsClipCombine_kSubtract, clipres); - } - else if (this != pRoot) - rc.SetClipRect(brect, nsClipCombine_kSubtract, clipres); - } - - aResult = clipres; - } - - return NS_OK; + return NS_OK; } NS_IMETHODIMP nsView :: Paint(nsIRenderingContext& rc, const nsIRegion& region, @@ -1083,6 +1039,32 @@ NS_IMETHODIMP nsView::GetAutoZIndex(PRBool &aAutoZIndex) const return NS_OK; } + +NS_IMETHODIMP nsView::SetFloating(PRBool aFloatingView) +{ + if (aFloatingView) + mVFlags |= NS_VIEW_PUBLIC_FLAG_FLOATING; + else + mVFlags &= ~NS_VIEW_PUBLIC_FLAG_FLOATING; + +#if 0 + // recursively make all sub-views "floating" grr. + nsIView *child = mFirstChild; + while (nsnull != child) { + child->SetFloating(aFloatingView); + child->GetNextSibling(child); + } +#endif + + return NS_OK; +} + +NS_IMETHODIMP nsView::GetFloating(PRBool &aFloatingView) const +{ + aFloatingView = ((mVFlags & NS_VIEW_PUBLIC_FLAG_FLOATING) != 0); + return NS_OK; +} + NS_IMETHODIMP nsView :: SetParent(nsIView *aParent) { mParent = aParent; diff --git a/mozilla/view/src/nsView.h b/mozilla/view/src/nsView.h index 222706c3523..d3bc6c0faf4 100644 --- a/mozilla/view/src/nsView.h +++ b/mozilla/view/src/nsView.h @@ -74,6 +74,8 @@ public: NS_IMETHOD GetZIndex(PRInt32 &aZIndex) const; NS_IMETHOD SetAutoZIndex(PRBool aAutoZIndex); NS_IMETHOD GetAutoZIndex(PRBool &aAutoZIndex) const; + NS_IMETHOD SetFloating(PRBool aFloatingView); + NS_IMETHOD GetFloating(PRBool &aFloatingView) const; NS_IMETHOD SetParent(nsIView *aParent); NS_IMETHOD GetParent(nsIView *&aParent) const; NS_IMETHOD GetNextSibling(nsIView *&aNextSibling) const; diff --git a/mozilla/view/src/nsViewManager.cpp b/mozilla/view/src/nsViewManager.cpp index fd8d17da8ab..9780fd40c08 100644 --- a/mozilla/view/src/nsViewManager.cpp +++ b/mozilla/view/src/nsViewManager.cpp @@ -658,6 +658,14 @@ void nsViewManager :: RenderViews(nsIView *aRootView, nsIRenderingContext& aRC, { #ifdef NEW_COMPOSITOR + PRBool isFloatingView = PR_FALSE; + if (NS_SUCCEEDED(aRootView->GetFloating(isFloatingView)) && isFloatingView) { + // floating views are rendered locally (and act globally). + // Paint the view. The clipping rect was set above set don't clip again. + aRootView->Paint(aRC, aRect, NS_VIEW_FLAG_CLIP_SET, aResult); + return; + } + #define SET_STATE(x) { prevstate = state; state = (x); } PRInt32 flatlen = 0, cnt; @@ -1770,6 +1778,11 @@ NS_IMETHODIMP nsViewManager :: InsertChild(nsIView *parent, nsIView *child, nsIV UpdateTransCnt(nsnull, child); + // if the parent view is marked as "floating", make the newly added view float as well. + PRBool isFloating = PR_FALSE; + parent->GetFloating(isFloating); + child->SetFloating(isFloating); + //and mark this area as dirty if the view is visible... nsViewVisibility visibility; @@ -1817,9 +1830,13 @@ NS_IMETHODIMP nsViewManager :: InsertChild(nsIView *parent, nsIView *child, PRIn UpdateTransCnt(nsnull, child); + // if the parent view is marked as "floating", make the newly added view float as well. + PRBool isFloating = PR_FALSE; + parent->GetFloating(isFloating); + child->SetFloating(isFloating); + //and mark this area as dirty if the view is visible... nsViewVisibility visibility; - child->GetVisibility(visibility); if (nsViewVisibility_kHide != visibility) diff --git a/mozilla/view/src/nsViewManager2.cpp b/mozilla/view/src/nsViewManager2.cpp index 9e6dfabfc2a..5179feccf31 100755 --- a/mozilla/view/src/nsViewManager2.cpp +++ b/mozilla/view/src/nsViewManager2.cpp @@ -39,7 +39,7 @@ static NS_DEFINE_IID(kRenderingContextCID, NS_RENDERING_CONTEXT_CID); #define UPDATE_QUANTUM 1000 / 40 -//#define NO_DOUBLE_BUFFER +#define NO_DOUBLE_BUFFER //display list flags #define RENDER_VIEW 0x0000 @@ -129,12 +129,11 @@ nsViewManager2::~nsViewManager2() ((nsnull != mDrawingSurface) || (nsnull != gOffScreen) || (nsnull != gRed) || (nsnull != gBlue))) { - nsIRenderingContext *rc; - + nsCOMPtr rc; nsresult rv = nsComponentManager::CreateInstance(kRenderingContextCID, nsnull, NS_GET_IID(nsIRenderingContext), - (void **)&rc); + getter_AddRefs(rc)); if (NS_OK == rv) { @@ -149,8 +148,6 @@ nsViewManager2::~nsViewManager2() if (nsnull != gBlue) rc->DestroyDrawingSurface(gBlue); - - NS_RELEASE(rc); } mDrawingSurface = nsnull; @@ -381,7 +378,7 @@ NS_IMETHODIMP nsViewManager2::ResetScrolling(void) void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, nsIRegion *region, PRUint32 aUpdateFlags) { nsRect wrect; - nsIRenderingContext *localcx = nsnull; + nsCOMPtr localcx; nsDrawingSurface ds = nsnull; if (PR_FALSE == mRefreshEnabled) @@ -403,24 +400,24 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, nsIR if (nsnull == aContext) { - localcx = CreateRenderingContext(*aView); + localcx = getter_AddRefs(CreateRenderingContext(*aView)); //couldn't get rendering context. this is ok at init time atleast if (nsnull == localcx) return; - } - else + } else { + // plain assignment grabs another reference. localcx = aContext; + } // notify the listeners. if (nsnull != mCompositeListeners) { PRUint32 listenerCount; if (NS_SUCCEEDED(mCompositeListeners->Count(&listenerCount))) { - nsICompositeListener* listener; + nsCOMPtr listener; for (PRUint32 i = 0; i < listenerCount; i++) { - if (NS_SUCCEEDED(mCompositeListeners->QueryElementAt(i, NS_GET_IID(nsICompositeListener), (void**)&listener))) { + if (NS_SUCCEEDED(mCompositeListeners->QueryElementAt(i, NS_GET_IID(nsICompositeListener), getter_AddRefs(listener)))) { listener->WillRefreshRegion(this, aView, aContext, region, aUpdateFlags); - NS_RELEASE(listener); } } } @@ -428,15 +425,10 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, nsIR if (aUpdateFlags & NS_VMREFRESH_DOUBLE_BUFFER) { - nsIWidget* widget; - - aView->GetWidget(widget); + nsCOMPtr widget; + aView->GetWidget(*getter_AddRefs(widget)); widget->GetClientBounds(wrect); - wrect.x = wrect.y = 0; - - NS_RELEASE(widget); - ds = GetDrawingSurface(*localcx, wrect); } @@ -455,9 +447,6 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, nsIR if ((aUpdateFlags & NS_VMREFRESH_DOUBLE_BUFFER) && ds) localcx->CopyOffScreenBits(ds, wrect.x, wrect.y, wrect, NS_COPYBITS_USE_SOURCE_CLIP_REGION); - if (localcx != aContext) - NS_RELEASE(localcx); - // Subtract the area we just painted from the dirty region if ((nsnull != region) && !region->IsEmpty()) { @@ -478,11 +467,10 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, nsIR if (nsnull != mCompositeListeners) { PRUint32 listenerCount; if (NS_SUCCEEDED(mCompositeListeners->Count(&listenerCount))) { - nsICompositeListener* listener; + nsCOMPtr listener; for (PRUint32 i = 0; i < listenerCount; i++) { - if (NS_SUCCEEDED(mCompositeListeners->QueryElementAt(i, NS_GET_IID(nsICompositeListener), (void**)&listener))) { + if (NS_SUCCEEDED(mCompositeListeners->QueryElementAt(i, NS_GET_IID(nsICompositeListener), getter_AddRefs(listener)))) { listener->DidRefreshRegion(this, aView, aContext, region, aUpdateFlags); - NS_RELEASE(listener); } } } @@ -492,7 +480,7 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, nsIR void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, const nsRect *rect, PRUint32 aUpdateFlags) { nsRect wrect, brect; - nsIRenderingContext *localcx = nsnull; + nsCOMPtr localcx; nsDrawingSurface ds = nsnull; if (PR_FALSE == mRefreshEnabled) @@ -516,24 +504,24 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, cons if (nsnull == aContext) { - localcx = CreateRenderingContext(*aView); + localcx = getter_AddRefs(CreateRenderingContext(*aView)); //couldn't get rendering context. this is ok if at startup if (nsnull == localcx) return; - } - else + } else { + // plain assignment adds a ref localcx = aContext; + } // notify the listeners. if (nsnull != mCompositeListeners) { PRUint32 listenerCount; if (NS_SUCCEEDED(mCompositeListeners->Count(&listenerCount))) { - nsICompositeListener* listener; + nsCOMPtr listener; for (PRUint32 i = 0; i < listenerCount; i++) { - if (NS_SUCCEEDED(mCompositeListeners->QueryElementAt(i, NS_GET_IID(nsICompositeListener), (void**)&listener))) { + if (NS_SUCCEEDED(mCompositeListeners->QueryElementAt(i, NS_GET_IID(nsICompositeListener), getter_AddRefs(listener)))) { listener->WillRefreshRect(this, aView, aContext, rect, aUpdateFlags); - NS_RELEASE(listener); } } } @@ -541,16 +529,11 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, cons if (aUpdateFlags & NS_VMREFRESH_DOUBLE_BUFFER) { - nsIWidget* widget; - - aView->GetWidget(widget); + nsCOMPtr widget; + aView->GetWidget(*getter_AddRefs(widget)); widget->GetClientBounds(wrect); - brect = wrect; wrect.x = wrect.y = 0; - - NS_RELEASE(widget); - ds = GetDrawingSurface(*localcx, wrect); } @@ -565,13 +548,9 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, cons if ((aUpdateFlags & NS_VMREFRESH_DOUBLE_BUFFER) && ds) localcx->CopyOffScreenBits(ds, wrect.x, wrect.y, wrect, NS_COPYBITS_USE_SOURCE_CLIP_REGION); - - if (localcx != aContext) - NS_RELEASE(localcx); - #if 0 // Subtract the area we just painted from the dirty region - nsIRegion *dirtyRegion; + nsIRegion* dirtyRegion; aView->GetDirtyRegion(dirtyRegion); if ((nsnull != dirtyRegion) && !dirtyRegion->IsEmpty()) @@ -595,11 +574,10 @@ void nsViewManager2::Refresh(nsIView *aView, nsIRenderingContext *aContext, cons if (nsnull != mCompositeListeners) { PRUint32 listenerCount; if (NS_SUCCEEDED(mCompositeListeners->Count(&listenerCount))) { - nsICompositeListener* listener; + nsCOMPtr listener; for (PRUint32 i = 0; i < listenerCount; i++) { - if (NS_SUCCEEDED(mCompositeListeners->QueryElementAt(i, NS_GET_IID(nsICompositeListener), (void**)&listener))) { + if (NS_SUCCEEDED(mCompositeListeners->QueryElementAt(i, NS_GET_IID(nsICompositeListener), getter_AddRefs(listener)))) { listener->DidRefreshRect(this, aView, aContext, rect, aUpdateFlags); - NS_RELEASE(listener); } } } @@ -619,76 +597,108 @@ typedef enum COMPOSITION_DONE } nsCompState; -//bit shifts -#define TRANS_PROPERTY_TRANS 0 -#define TRANS_PROPERTY_OPACITY 1 +#ifdef XP_MAC +#include +static Boolean caps_lock() +{ + EventRecord event; + ::OSEventAvail(0, &event); + return ((event.modifiers & alphaLock) != 0); +} +#else +#define caps_lock() (0) +#endif void nsViewManager2::RenderViews(nsIView *aRootView, nsIRenderingContext& aRC, const nsRect& aRect, PRBool &aResult) { - // Paint the view. The clipping rect was set above set don't clip again. - aRootView->Paint(aRC, aRect, NS_VIEW_FLAG_CLIP_SET, aResult); + PRBool isFloatingView = PR_FALSE; + if (NS_SUCCEEDED(aRootView->GetFloating(isFloatingView)) && isFloatingView) { + // floating views are rendered locally (and act globally). + // Paint the view. The clipping rect was set above set don't clip again. + aRootView->Paint(aRC, aRect, NS_VIEW_FLAG_CLIP_SET, aResult); + } else { + // otherwise, use display list to render non-floating views. + PRBool clipEmpty; + + // create the display list. shouldn't we be able to just create this once? + nsPoint origin(0, 0); + ComputeViewOffset(aRootView, &origin.x, &origin.y, 1); + + PRInt32 count = 0; + CreateDisplayList(mRootView, &count, origin.x, origin.y, aRootView, &aRect); + + // draw all views in the display list, from back to front. + for (PRInt32 i = count - 1; i>= 0; --i) { + DisplayListElement* element = static_cast(mDisplayList->ElementAt(i)); + if (element->mFlags & PUSH_CLIP) { + aRC.PushState(); + aRC.SetClipRect(element->mClip, nsClipCombine_kIntersect, clipEmpty); + } else + if (element->mFlags & POP_CLIP) { + aRC.PopState(clipEmpty); + } else { + RenderView(element->mView, aRC, aRect, element->mClip, aResult); + } + } + } } void nsViewManager2::RenderView(nsIView *aView, nsIRenderingContext &aRC, const nsRect &aDamageRect, nsRect &aGlobalRect, PRBool &aResult) { - nsRect drect; + nsRect drect; - NS_ASSERTION(!(nsnull == aView), "no view"); + NS_ASSERTION(!(nsnull == aView), "no view"); - aRC.PushState(); + aRC.PushState(); - aRC.Translate(aGlobalRect.x, aGlobalRect.y); + aRC.Translate(aGlobalRect.x, aGlobalRect.y); - drect.IntersectRect(aDamageRect, aGlobalRect); + drect.IntersectRect(aDamageRect, aGlobalRect); - drect.x -= aGlobalRect.x; - drect.y -= aGlobalRect.y; + drect.x -= aGlobalRect.x; + drect.y -= aGlobalRect.y; - aView->Paint(aRC, drect, NS_VIEW_FLAG_JUST_PAINT, aResult); + aView->Paint(aRC, drect, NS_VIEW_FLAG_JUST_PAINT, aResult); - aRC.PopState(aResult); + aRC.PopState(aResult); } void nsViewManager2::UpdateDirtyViews(nsIView *aView, nsRect *aParentRect) const { - nsRect bounds; - aView->GetBounds(bounds); + nsRect bounds; + aView->GetBounds(bounds); - // translate parent rect into child coords. - nsRect parDamage; - if (nsnull != aParentRect) { - parDamage = *aParentRect; - parDamage.IntersectRect(bounds, parDamage); - parDamage.MoveBy(-bounds.x, -bounds.y); - } else - parDamage = bounds; + // translate parent rect into child coords. + nsRect parDamage; + if (nsnull != aParentRect) { + parDamage = *aParentRect; + parDamage.IntersectRect(bounds, parDamage); + parDamage.MoveBy(-bounds.x, -bounds.y); + } else + parDamage = bounds; - if (PR_FALSE == parDamage.IsEmpty()) { - nsIWidget *widget; - aView->GetWidget(widget); - if (nsnull != widget) { - float scale; - nsRect pixrect = parDamage; + if (PR_FALSE == parDamage.IsEmpty()) { + nsCOMPtr widget; + aView->GetWidget(*getter_AddRefs(widget)); + if (nsnull != widget) { + nsRect pixrect = parDamage; - mContext->GetAppUnitsToDevUnits(scale); - pixrect.ScaleRoundOut(scale); + float scale; + mContext->GetAppUnitsToDevUnits(scale); + pixrect.ScaleRoundOut(scale); -//printf("invalidating: view %x (pix) %d, %d\n", aView, pixrect.width, pixrect.height); - widget->Invalidate(pixrect, PR_FALSE); + //printf("invalidating: view %x (pix) %d, %d\n", aView, pixrect.width, pixrect.height); + widget->Invalidate(pixrect, PR_FALSE); + } + } - NS_RELEASE(widget); - } - } - - // Check our child views - nsIView *child; - - aView->GetChild(0, child); - - while (nsnull != child) { - UpdateDirtyViews(child, &parDamage); - child->GetNextSibling(child); - } + // Check our child views + nsIView *child; + aView->GetChild(0, child); + while (nsnull != child) { + UpdateDirtyViews(child, &parDamage); + child->GetNextSibling(child); + } } void nsViewManager2::ProcessPendingUpdates(nsIView* aView) @@ -1094,6 +1104,12 @@ NS_IMETHODIMP nsViewManager2::InsertChild(nsIView *parent, nsIView *child, nsIVi UpdateTransCnt(nsnull, child); + // if the parent view is marked as "floating", make the newly added view float as well. + PRBool isFloating = PR_FALSE; + parent->GetFloating(isFloating); + if (isFloating) + child->SetFloating(isFloating); + //and mark this area as dirty if the view is visible... nsViewVisibility visibility; @@ -1141,9 +1157,14 @@ NS_IMETHODIMP nsViewManager2::InsertChild(nsIView *parent, nsIView *child, PRInt UpdateTransCnt(nsnull, child); + // if the parent view is marked as "floating", make the newly added view float as well. + PRBool isFloating = PR_FALSE; + parent->GetFloating(isFloating); + if (isFloating) + child->SetFloating(isFloating); + //and mark this area as dirty if the view is visible... nsViewVisibility visibility; - child->GetVisibility(visibility); if (nsViewVisibility_kHide != visibility) @@ -1429,27 +1450,25 @@ NS_IMETHODIMP nsViewManager2::SetViewOpacity(nsIView *aView, float aOpacity) NS_IMETHODIMP nsViewManager2::SetViewObserver(nsIViewObserver *aObserver) { - mObserver = aObserver; - return NS_OK; + mObserver = aObserver; + return NS_OK; } NS_IMETHODIMP nsViewManager2::GetViewObserver(nsIViewObserver *&aObserver) { - if (nsnull != mObserver) - { - aObserver = mObserver; - NS_ADDREF(mObserver); - return NS_OK; - } - else - return NS_ERROR_NO_INTERFACE; + if (nsnull != mObserver) { + aObserver = mObserver; + NS_ADDREF(mObserver); + return NS_OK; + } else + return NS_ERROR_NO_INTERFACE; } NS_IMETHODIMP nsViewManager2::GetDeviceContext(nsIDeviceContext *&aContext) { - NS_IF_ADDREF(mContext); - aContext = mContext; - return NS_OK; + NS_IF_ADDREF(mContext); + aContext = mContext; + return NS_OK; } #ifndef max @@ -1458,39 +1477,37 @@ NS_IMETHODIMP nsViewManager2::GetDeviceContext(nsIDeviceContext *&aContext) nsDrawingSurface nsViewManager2::GetDrawingSurface(nsIRenderingContext &aContext, nsRect& aBounds) { - if ((nsnull == mDrawingSurface) - || (mDSBounds.width < aBounds.width) - || (mDSBounds.height < aBounds.height)) - { + if ((nsnull == mDrawingSurface) + || (mDSBounds.width < aBounds.width) + || (mDSBounds.height < aBounds.height)) + { nsRect newBounds; newBounds.MoveTo(aBounds.x, aBounds.y); newBounds.width = max(aBounds.width, mDSBounds.width); newBounds.height = max(aBounds.height, mDSBounds.height); - if (mDrawingSurface) { - //destroy existing DS - aContext.DestroyDrawingSurface(mDrawingSurface); - mDrawingSurface = nsnull; - } + if (mDrawingSurface) { + //destroy existing DS + aContext.DestroyDrawingSurface(mDrawingSurface); + mDrawingSurface = nsnull; + } - nsresult rv = aContext.CreateDrawingSurface(&newBounds, 0, mDrawingSurface); + nsresult rv = aContext.CreateDrawingSurface(&newBounds, 0, mDrawingSurface); if (NS_SUCCEEDED(rv)) { - mDSBounds = newBounds; + mDSBounds = newBounds; aContext.SelectOffScreenDrawingSurface(mDrawingSurface); - } - else { - mDSBounds.SetRect(0,0,0,0); - mDrawingSurface = nsnull; - } - } - else { + } else { + mDSBounds.SetRect(0,0,0,0); + mDrawingSurface = nsnull; + } + } else { aContext.SelectOffScreenDrawingSurface(mDrawingSurface); float p2t; - mContext->GetDevUnitsToAppUnits(p2t); - nsRect bounds = aBounds; - bounds *= p2t; + mContext->GetDevUnitsToAppUnits(p2t); + nsRect bounds = aBounds; + bounds *= p2t; PRBool clipEmpty; aContext.SetClipRect(bounds, nsClipCombine_kReplace, clipEmpty); @@ -1498,9 +1515,9 @@ nsDrawingSurface nsViewManager2::GetDrawingSurface(nsIRenderingContext &aContext nscolor col = NS_RGB(255,255,255); aContext.SetColor(col); //aContext.FillRect(bounds); - } + } - return mDrawingSurface; + return mDrawingSurface; } NS_IMETHODIMP nsViewManager2::ShowQuality(PRBool aShow) @@ -1530,14 +1547,13 @@ NS_IMETHODIMP nsViewManager2::SetQuality(nsContentQuality aQuality) nsIRenderingContext * nsViewManager2::CreateRenderingContext(nsIView &aView) { nsIView *par = &aView; - nsIWidget *win; + nsCOMPtr win; nsIRenderingContext *cx = nsnull; nscoord x, y, ax = 0, ay = 0; do { - par->GetWidget(win); - + par->GetWidget(*getter_AddRefs(win)); if (nsnull != win) break; @@ -1565,8 +1581,6 @@ nsIRenderingContext * nsViewManager2::CreateRenderingContext(nsIView &aView) if (nsnull != cx) cx->Translate(ax, ay); - - NS_RELEASE(win); } return cx; @@ -1766,128 +1780,118 @@ PRBool nsViewManager2::CreateDisplayList(nsIView *aView, PRInt32 *aIndex, const nsRect *aDamageRect, nsIView *aTopView, nsVoidArray *aArray, nscoord aX, nscoord aY) { - PRInt32 numkids, zindex; - PRBool hasWidget, retval = PR_FALSE; - nsIClipView *clipper = nsnull; - nsPoint *point; - nsIView *child = nsnull; + PRInt32 numkids, zindex; + PRBool retval = PR_FALSE; + nsIClipView *clipper = nsnull; + nsPoint *point; + nsIView *child = nsnull; - NS_ASSERTION(!(!aView), "no view"); - NS_ASSERTION(!(!aIndex), "no index"); + NS_ASSERTION(!(!aView), "no view"); + NS_ASSERTION(!(!aIndex), "no index"); - if (!aArray) - { - if (!mDisplayList) - mDisplayList = new nsVoidArray(8); + if (!aArray) { + if (!mDisplayList) + mDisplayList = new nsVoidArray(8); - aArray = mDisplayList; + aArray = mDisplayList; + if (!aArray) + return PR_TRUE; + } - if (!aArray) - return PR_TRUE; - } + if (!aTopView) + aTopView = aView; - if (!aTopView) - aTopView = aView; + nsRect lrect; + aView->GetBounds(lrect); - nsRect lrect; + if (aView == aTopView) { + lrect.x = 0; + lrect.y = 0; + } - aView->GetBounds(lrect); + lrect.x += aX; + lrect.y += aY; - if (aView == aTopView) - { - lrect.x = 0; - lrect.y = 0; - } + aView->QueryInterface(NS_GET_IID(nsIClipView), (void **)&clipper); + aView->GetChildCount(numkids); + aView->GetScratchPoint(&point); - lrect.x += aX; - lrect.y += aY; + PRBool hasWidget = DoesViewHaveNativeWidget(*aView); - aView->QueryInterface(NS_GET_IID(nsIClipView), (void **)&clipper); - aView->GetChildCount(numkids); - aView->GetScratchPoint(&point); + if (numkids > 0) { + if (clipper && (!hasWidget || (hasWidget && point->x))) { + lrect.x -= aOriginX; + lrect.y -= aOriginY; - hasWidget = DoesViewHaveNativeWidget(*aView); + retval = AddToDisplayList(aArray, aIndex, aView, lrect, POP_CLIP); - if (numkids > 0) - { - if (clipper && (!hasWidget || (hasWidget && point->x))) - { - lrect.x -= aOriginX; - lrect.y -= aOriginY; + if (retval) + return retval; - retval = AddToDisplayList(aArray, aIndex, aView, lrect, PUSH_CLIP); + lrect.x += aOriginX; + lrect.y += aOriginY; + } - if (retval) - return retval; + if (!hasWidget || (hasWidget && point->x)) + // if ((aView == aTopView) || (aView == aRealView)) + // if ((aView == aTopView) || !hasWidget || (aView == aRealView)) + // if ((aView == aTopView) || !(hasWidget && clipper) || (aView == aRealView)) + { + for (aView->GetChild(0, child); nsnull != child; child->GetNextSibling(child)) { + child->GetZIndex(zindex); + if (zindex < 0) + break; + retval = CreateDisplayList(child, aIndex, aOriginX, aOriginY, aRealView, aDamageRect, aTopView, aArray, lrect.x, lrect.y); + if (retval) + break; + } + } + } - lrect.x += aOriginX; - lrect.y += aOriginY; - } + lrect.x -= aOriginX; + lrect.y -= aOriginY; - if (!hasWidget || (hasWidget && point->x)) -// if ((aView == aTopView) || (aView == aRealView)) -// if ((aView == aTopView) || !hasWidget || (aView == aRealView)) -// if ((aView == aTopView) || !(hasWidget && clipper) || (aView == aRealView)) - { - for (aView->GetChild(0, child); nsnull != child; child->GetNextSibling(child)) - { - child->GetZIndex(zindex); - if (zindex < 0) - break; - retval = CreateDisplayList(child, aIndex, aOriginX, aOriginY, aRealView, aDamageRect, aTopView, aArray, lrect.x, lrect.y); - if (retval) - break; - } - } - } + // if (clipper) + if (clipper && (!hasWidget || (hasWidget && point->x))) { + if (numkids > 0) + retval = AddToDisplayList(aArray, aIndex, aView, lrect, PUSH_CLIP); + } else if (!retval) { + nsViewVisibility vis; + float opacity; + PRBool overlap; + PRBool trans; + nsRect irect; - lrect.x -= aOriginX; - lrect.y -= aOriginY; + aView->GetVisibility(vis); + aView->GetOpacity(opacity); + aView->HasTransparency(trans); -// if (clipper) - if (clipper && (!hasWidget || (hasWidget && point->x))) - { - if (numkids > 0) - retval = AddToDisplayList(aArray, aIndex, aView, lrect, POP_CLIP); - } - else if (!retval) - { - nsViewVisibility vis; - float opacity; - PRBool overlap; - PRBool trans; - nsRect irect; + if (aDamageRect) + overlap = irect.IntersectRect(lrect, *aDamageRect); + else + overlap = PR_TRUE; - aView->GetVisibility(vis); - aView->GetOpacity(opacity); - aView->HasTransparency(trans); + if ((nsViewVisibility_kShow == vis) && (opacity > 0.0f) && overlap) + { + retval = AddToDisplayList(aArray, aIndex, aView, lrect, 0); - if (aDamageRect) - overlap = irect.IntersectRect(lrect, *aDamageRect); - else - overlap = PR_TRUE; + if (retval || !trans && (opacity == 1.0f) && (irect == *aDamageRect)) + retval = PR_TRUE; + } - if ((nsViewVisibility_kShow == vis) && (opacity > 0.0f) && overlap) - { - retval = AddToDisplayList(aArray, aIndex, aView, lrect, 0); + // any children with negative z-indices? + if (!retval && nsnull != child) { + lrect.x += aOriginX; + lrect.y += aOriginY; + for (; nsnull != child; child->GetNextSibling(child)) { + retval = CreateDisplayList(child, aIndex, aOriginX, aOriginY, aRealView, aDamageRect, aTopView, aArray, lrect.x, lrect.y); + if (retval) + break; + } + } + } - if (retval || !trans && (opacity == 1.0f) && (irect == *aDamageRect)) - retval = PR_TRUE; - } - - // any children with negative z-indices? - if (!retval && nsnull != child) { - lrect.x += aOriginX; - lrect.y += aOriginY; - for (; nsnull != child; child->GetNextSibling(child)) { - retval = CreateDisplayList(child, aIndex, aOriginX, aOriginY, aRealView, aDamageRect, aTopView, aArray, lrect.x, lrect.y); - if (retval) - break; - } - } - } - - return retval; + return retval; } PRBool nsViewManager2::AddToDisplayList(nsVoidArray *aArray, PRInt32 *aIndex, nsIView *aView, nsRect &aRect, PRUint32 aFlags) @@ -1998,23 +2002,11 @@ void nsViewManager2::ComputeViewOffset(nsIView *aView, nscoord *aX, nscoord *aY, PRBool nsViewManager2::DoesViewHaveNativeWidget(nsIView &aView) { - nsIWidget *widget; - PRBool retval = PR_FALSE; - - aView.GetWidget(widget); - + nsCOMPtr widget; + aView.GetWidget(*getter_AddRefs(widget)); if (nsnull != widget) - { - void *nativewidget; - - nativewidget = widget->GetNativeData(NS_NATIVE_WIDGET); - NS_RELEASE(widget); - - if (nsnull != nativewidget) - retval = PR_TRUE; - } - - return retval; + return (nsnull != widget->GetNativeData(NS_NATIVE_WIDGET)); + return PR_FALSE; } void nsViewManager2::PauseTimer(void)