From 404c0a78e424c17dcecbd047304a8f9a6cc93ae8 Mon Sep 17 00:00:00 2001 From: "michaelp%netscape.com" Date: Sun, 26 Jul 1998 04:24:42 +0000 Subject: [PATCH] form elements, etc. (i.e. sub widgets) now scroll smoothly. --- view/public/nsIScrollableView.h | 7 +-- view/public/nsIViewManager.h | 2 +- view/src/nsScrollingView.cpp | 102 +++++++++++++++++--------------- view/src/nsScrollingView.h | 4 +- view/src/nsView.cpp | 27 +++++++++ view/src/nsViewManager.cpp | 3 +- widget/src/windows/nsWindow.cpp | 2 +- 7 files changed, 87 insertions(+), 60 deletions(-) diff --git a/view/public/nsIScrollableView.h b/view/public/nsIScrollableView.h index 83ae7bc4d1a4..80ff6fe37abc 100644 --- a/view/public/nsIScrollableView.h +++ b/view/public/nsIScrollableView.h @@ -116,12 +116,7 @@ public: */ NS_IMETHOD ScrollTo(nscoord aX, nscoord aY, PRUint32 aUpdateFlags) = 0; - /** - * Get the view that clips the contents of the scrolling view - * @param aClipView out param to hold view pointer - * @return error status - */ - NS_IMETHOD GetClipView(nsIView ** aClipView) = 0; + NS_IMETHOD GetClipSize(nscoord *aX, nscoord *aY) = 0; }; #endif diff --git a/view/public/nsIViewManager.h b/view/public/nsIViewManager.h index 63df15a348f7..be663f52c471 100644 --- a/view/public/nsIViewManager.h +++ b/view/public/nsIViewManager.h @@ -386,7 +386,7 @@ public: #define NS_VMREFRESH_IMMEDIATE 0x0004 //prevent "sync painting" #define NS_VMREFRESH_NO_SYNC 0x0008 -//if the total damage area is greater than 75% of the +//if the total damage area is greater than 25% of the //area of the root view, use double buffering #define NS_VMREFRESH_AUTO_DOUBLE_BUFFER 0x0010 diff --git a/view/src/nsScrollingView.cpp b/view/src/nsScrollingView.cpp index 0e83166e6128..ee361b29ed55 100644 --- a/view/src/nsScrollingView.cpp +++ b/view/src/nsScrollingView.cpp @@ -30,6 +30,7 @@ static NS_DEFINE_IID(kIScrollbarIID, NS_ISCROLLBAR_IID); static NS_DEFINE_IID(kIScrollableViewIID, NS_ISCROLLABLEVIEW_IID); +static NS_DEFINE_IID(kWidgetCID, NS_CHILD_CID); class ScrollBarView : public nsView { @@ -312,7 +313,7 @@ nsScrollingView :: nsScrollingView() mHScrollBarView = nsnull; mCornerView = nsnull; mScrollPref = nsScrollPreference_kAuto; - mClipView = nsnull; + mClipX = mClipY = 0; } nsScrollingView :: ~nsScrollingView() @@ -336,12 +337,6 @@ nsScrollingView :: ~nsScrollingView() NS_RELEASE(mCornerView); mCornerView = nsnull; } - - if (nsnull != mClipView) - { - NS_RELEASE(mClipView); - mClipView = nsnull; - } } nsresult nsScrollingView :: QueryInterface(const nsIID& aIID, void** aInstancePtr) @@ -383,6 +378,9 @@ nsresult nsScrollingView :: Init(nsIViewManager* aManager, nsViewVisibility aVisibilityFlag) { nsresult rv; + + mClipX = aBounds.width; + mClipY = aBounds.height; rv = nsView :: Init(aManager, aBounds, aParent, aWindowIID, aWidgetInitData, aNative, aZIndex, aClip, aOpacity, aVisibilityFlag); @@ -411,28 +409,6 @@ nsresult nsScrollingView :: Init(nsIViewManager* aManager, mViewManager->InsertChild(this, mCornerView, -1); } -#if 0 - // Create a view for clipping - - mClipView = new ClipView(); - - if (nsnull != mClipView) - { - NS_ADDREF(mClipView); - - nsRect trect; - - trect.width = aBounds.XMost() - NS_TO_INT_ROUND(dx->GetScrollBarWidth()); - trect.x = 0; - trect.height = aBounds.YMost() - NS_TO_INT_ROUND(dx->GetScrollBarHeight()); - trect.y = 0; - - rv = mClipView->Init(mViewManager, trect, this, nsnull, nsnull, nsnull, -1); - - mViewManager->InsertChild(this, mCornerView, -1); - } -#endif - // Create a view for a vertical scrollbar mVScrollBarView = new ScrollBarView(this); @@ -449,7 +425,7 @@ nsresult nsScrollingView :: Init(nsIViewManager* aManager, static NS_DEFINE_IID(kCScrollbarIID, NS_VERTSCROLLBAR_CID); - rv = mVScrollBarView->Init(mViewManager, trect, this, &kCScrollbarIID, nsnull, nsnull, -2); + rv = mVScrollBarView->Init(mViewManager, trect, this, &kCScrollbarIID, nsnull, aNative, -3); mViewManager->InsertChild(this, mVScrollBarView, -3); } @@ -470,7 +446,7 @@ nsresult nsScrollingView :: Init(nsIViewManager* aManager, static NS_DEFINE_IID(kCHScrollbarIID, NS_HORZSCROLLBAR_CID); - rv = mHScrollBarView->Init(mViewManager, trect, this, &kCHScrollbarIID, nsnull, nsnull, -2); + rv = mHScrollBarView->Init(mViewManager, trect, this, &kCHScrollbarIID, nsnull, aNative, -3); mViewManager->InsertChild(this, mHScrollBarView, -3); } @@ -487,18 +463,46 @@ void nsScrollingView :: SetDimensions(nscoord width, nscoord height) nsRect trect; nsIPresContext *cx = mViewManager->GetPresContext(); nsIDeviceContext *dx = cx->GetDeviceContext(); + nscoord showHorz = 0, showVert = 0; + nscoord scrollWidth = NS_TO_INT_ROUND(dx->GetScrollBarWidth()); + nscoord scrollHeight = NS_TO_INT_ROUND(dx->GetScrollBarHeight()); if (nsnull != mCornerView) { mCornerView->GetDimensions(&trect.width, &trect.height); - trect.y = height - NS_TO_INT_ROUND(dx->GetScrollBarHeight()); - trect.x = width - NS_TO_INT_ROUND(dx->GetScrollBarWidth()); + trect.y = height - scrollHeight; + trect.x = width - scrollWidth; mCornerView->SetBounds(trect); } - nsView :: SetDimensions(width, height); + if (mHScrollBarView && (mHScrollBarView->GetVisibility() == nsViewVisibility_kShow)) + showHorz = scrollHeight; + + if (mVScrollBarView && (mVScrollBarView->GetVisibility() == nsViewVisibility_kShow)) + showVert = scrollWidth; + +// nsView :: SetDimensions(width, height); + + mBounds.SizeTo(width, height); + + if (nsnull != mWindow) + { + float t2p = cx->GetTwipsToPixels(); + + mClipX = width - showVert; + mClipY = height - showHorz; + + mWindow->Resize(NS_TO_INT_ROUND(t2p * (width - showVert)), + NS_TO_INT_ROUND(t2p * (height - showHorz)), + PR_TRUE); + } + else + { + mClipX = width; + mClipY = height; + } if (nsnull != mVScrollBarView) { @@ -506,11 +510,10 @@ void nsScrollingView :: SetDimensions(nscoord width, nscoord height) trect.height = height; - if ((mHScrollBarView && (mHScrollBarView->GetVisibility() == nsViewVisibility_kShow)) || - (mCornerView && (mCornerView->GetVisibility() == nsViewVisibility_kShow))) - trect.height -= NS_TO_INT_ROUND(dx->GetScrollBarHeight()); + if (showHorz || (mCornerView && (mCornerView->GetVisibility() == nsViewVisibility_kShow))) + trect.height -= scrollHeight; - trect.x = width - NS_TO_INT_ROUND(dx->GetScrollBarWidth()); + trect.x = width - scrollWidth; trect.y = 0; mVScrollBarView->SetBounds(trect); @@ -522,11 +525,10 @@ void nsScrollingView :: SetDimensions(nscoord width, nscoord height) trect.width = width; - if ((mVScrollBarView && (mVScrollBarView->GetVisibility() == nsViewVisibility_kShow)) || - (mCornerView && (mCornerView->GetVisibility() == nsViewVisibility_kShow))) - trect.width -= NS_TO_INT_ROUND(dx->GetScrollBarWidth()); + if (showVert || (mCornerView && (mCornerView->GetVisibility() == nsViewVisibility_kShow))) + trect.width -= scrollWidth; - trect.y = height - NS_TO_INT_ROUND(dx->GetScrollBarHeight()); + trect.y = height - scrollHeight; trect.x = 0; mHScrollBarView->SetBounds(trect); @@ -656,10 +658,11 @@ void nsScrollingView :: HandleScrollEvent(nsGUIEvent *aEvent, PRUint32 aEventFla if (dy != 0) { - AdjustChildWidgets(this, this, 0, 0, px->GetTwipsToPixels()); +// AdjustChildWidgets(this, this, 0, 0, px->GetTwipsToPixels()); if (nsnull != mWindow) - mWindow->Scroll(0, dy, &clip); +// mWindow->Scroll(0, dy, &clip); + mWindow->Scroll(0, dy, nsnull); else mViewManager->UpdateView(this, nsnull, 0); } @@ -724,10 +727,11 @@ void nsScrollingView :: HandleScrollEvent(nsGUIEvent *aEvent, PRUint32 aEventFla if (dx != 0) { - AdjustChildWidgets(this, this, 0, 0, px->GetTwipsToPixels()); +// AdjustChildWidgets(this, this, 0, 0, px->GetTwipsToPixels()); if (nsnull != mWindow) - mWindow->Scroll(dx, 0, &clip); +// mWindow->Scroll(dx, 0, &clip); + mWindow->Scroll(dx, 0, nsnull); else mViewManager->UpdateView(this, nsnull, 0); } @@ -1073,10 +1077,10 @@ nsScrollingView :: ScrollTo(nscoord aX, nscoord aY, PRUint32 aUpdateFlags) return NS_OK; } -NS_IMETHODIMP nsScrollingView :: GetClipView(nsIView ** aClipView) +NS_IMETHODIMP nsScrollingView :: GetClipSize(nscoord *aX, nscoord *aY) { - NS_IF_ADDREF(mClipView); - *aClipView = mClipView; + *aX = mClipX; + *aY = mClipY; return NS_OK; } diff --git a/view/src/nsScrollingView.h b/view/src/nsScrollingView.h index 4c0385ddfa93..dccd9768eb76 100644 --- a/view/src/nsScrollingView.h +++ b/view/src/nsScrollingView.h @@ -69,7 +69,7 @@ public: virtual void SetScrollPreference(nsScrollPreference aPref); virtual nsScrollPreference GetScrollPreference(void); NS_IMETHOD ScrollTo(nscoord aX, nscoord aY, PRUint32 aUpdateFlags); - NS_IMETHOD GetClipView(nsIView ** aClipView); + NS_IMETHOD GetClipSize(nscoord *aX, nscoord *aY); //private void ComputeScrollArea(nsIView *aView, nsRect &aRect, nscoord aOffX, nscoord aOffY); @@ -84,7 +84,7 @@ protected: nsIView *mHScrollBarView; nsIView *mCornerView; nsScrollPreference mScrollPref; - nsIView *mClipView; + nscoord mClipX, mClipY; }; #endif diff --git a/view/src/nsView.cpp b/view/src/nsView.cpp index 7351c53dfd68..f41103656aa5 100644 --- a/view/src/nsView.cpp +++ b/view/src/nsView.cpp @@ -32,6 +32,7 @@ #include "nsIScrollableView.h" static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID); +static NS_DEFINE_IID(kIScrollableViewIID, NS_ISCROLLABLEVIEW_IID); //#define SHOW_VIEW_BORDERS //#define HIDE_ALL_WIDGETS @@ -68,6 +69,32 @@ nsEventStatus PR_CALLBACK HandleEvent(nsGUIEvent *aEvent) { // Convert from pixels to twips float p2t = presContext->GetPixelsToTwips(); + nsIScrollableView *scrollView; + + //XXX hey look, a hack! :) i'm not proud of it, but it does + //work. the purpose is to prevent resizes of the view if the + //clip size (assumed to be the size of this window) is the same + //as the new size we get here. MMP + + if (NS_OK == rootView->QueryInterface(kIScrollableViewIID, (void **)&scrollView)) + { + nscoord sizex, sizey; + float t2p = presContext->GetTwipsToPixels(); + + scrollView->GetClipSize(&sizex, &sizey); + + NS_RELEASE(scrollView); + + if ((width == NS_TO_INT_ROUND(sizex * t2p)) && + (height == NS_TO_INT_ROUND(sizey * t2p))) + { + NS_IF_RELEASE(rootView); + NS_RELEASE(presContext); + NS_RELEASE(vm); + break; + } + } + vm->SetWindowDimensions(NS_TO_INT_ROUND(width * p2t), NS_TO_INT_ROUND(height * p2t)); result = nsEventStatus_eConsumeNoDefault; diff --git a/view/src/nsViewManager.cpp b/view/src/nsViewManager.cpp index 8a2d199c16b9..267d158c6bc7 100644 --- a/view/src/nsViewManager.cpp +++ b/view/src/nsViewManager.cpp @@ -555,8 +555,9 @@ void nsViewManager :: UpdateView(nsIView *aView, const nsRect &aRect, PRUint32 a mDirtyRegion->GetBoundingBox(&rrect.x, &rrect.y, &rrect.width, &rrect.height); rrect *= mContext->GetPixelsToTwips(); #endif + rrect.IntersectRect(rrect, vrect); - if ((((float)rrect.width * rrect.height) / (float)varea) > 0.75f) + if ((((float)rrect.width * rrect.height) / (float)varea) > 0.25f) aUpdateFlags |= NS_VMREFRESH_DOUBLE_BUFFER; else aUpdateFlags &= ~NS_VMREFRESH_DOUBLE_BUFFER; diff --git a/widget/src/windows/nsWindow.cpp b/widget/src/windows/nsWindow.cpp index d00edf35372d..c356b49804a3 100644 --- a/widget/src/windows/nsWindow.cpp +++ b/widget/src/windows/nsWindow.cpp @@ -1216,7 +1216,7 @@ void nsWindow::Scroll(PRInt32 aDx, PRInt32 aDy, nsRect *aClipRect) } ::ScrollWindowEx(mWnd, aDx, aDy, (nsnull != aClipRect) ? &trect : NULL, NULL, - NULL, NULL, SW_INVALIDATE); + NULL, NULL, SW_INVALIDATE | SW_SCROLLCHILDREN); ::UpdateWindow(mWnd); }