From e2209a9a1825853f80ce3904061d3e0c20da769b Mon Sep 17 00:00:00 2001 From: "troy%netscape.com" Date: Mon, 19 Oct 1998 00:44:28 +0000 Subject: [PATCH] Changed scrolling view to use a clip view and to slide the scrolled view up and down rather than maintain a logical scrolled offset git-svn-id: svn://10.0.0.236/trunk@13080 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/generic/nsHTMLFrame.cpp | 35 ++- mozilla/layout/generic/nsObjectFrame.cpp | 4 + mozilla/layout/html/base/src/nsHTMLFrame.cpp | 35 ++- .../layout/html/base/src/nsObjectFrame.cpp | 4 + .../layout/html/base/src/nsScrollFrame.cpp | 201 ++++++++++++------ mozilla/view/public/nsIScrollableView.h | 15 +- mozilla/view/public/nsIView.h | 7 - mozilla/view/public/nsIViewManager.h | 8 - mozilla/view/src/nsScrollingView.cpp | 186 ++++++---------- mozilla/view/src/nsScrollingView.h | 5 + mozilla/view/src/nsView.cpp | 74 ++----- mozilla/view/src/nsView.h | 3 + mozilla/view/src/nsViewManager.cpp | 37 ---- mozilla/view/src/nsViewManager.h | 2 - 14 files changed, 299 insertions(+), 317 deletions(-) diff --git a/mozilla/layout/generic/nsHTMLFrame.cpp b/mozilla/layout/generic/nsHTMLFrame.cpp index cd26792d729..e5ddbd7ba40 100644 --- a/mozilla/layout/generic/nsHTMLFrame.cpp +++ b/mozilla/layout/generic/nsHTMLFrame.cpp @@ -36,6 +36,10 @@ #include "nsHTMLAtoms.h" #include "nsIEventStateManager.h" #include "nsIDeviceContext.h" +#include "nsIScrollableView.h" + +// Interface IDs +static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID); class RootFrame : public nsContainerFrame { public: @@ -60,6 +64,8 @@ class RootContentFrame : public nsContainerFrame { public: RootContentFrame(nsIContent* aContent, nsIFrame* aParent); + NS_IMETHOD DidReflow(nsIPresContext& aPresContext, + nsDidReflowStatus aStatus); NS_IMETHOD Reflow(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, @@ -258,15 +264,40 @@ RootContentFrame::RootContentFrame(nsIContent* aContent, nsIFrame* aParent) NS_ASSERTION(nsnull != viewManager, "null view manager"); view->Init(viewManager, mRect, rootView); - viewManager->InsertChild(rootView, view, 0); - NS_RELEASE(viewManager); + // We expect the root view to be a scrolling view + nsIScrollableView* scrollView; + if (NS_SUCCEEDED(rootView->QueryInterface(kScrollViewIID, (void**)&scrollView))) { + scrollView->SetScrolledView(view); + } + // Remember our view SetView(view); + + // Don't allow our view's position to be changed. It's controlled by the + // scrollview + mState &= ~NS_FRAME_SYNC_FRAME_AND_VIEW; } } +NS_IMETHODIMP +RootContentFrame::DidReflow(nsIPresContext& aPresContext, + nsDidReflowStatus aStatus) +{ + if (NS_FRAME_REFLOW_FINISHED == aStatus) { + // Size the view. Don't position it... + nsIView* view; + nsIViewManager *vm; + + GetView(view); + view->GetViewManager(vm); + vm->ResizeView(view, mRect.width, mRect.height); + NS_RELEASE(vm); + } + return nsContainerFrame::DidReflow(aPresContext, aStatus); +} + // Determine the margins to place around the child frame. Note that // this applies to the frame in the page-frame when paginating, not // to the page-frame. diff --git a/mozilla/layout/generic/nsObjectFrame.cpp b/mozilla/layout/generic/nsObjectFrame.cpp index 4b96b2b8fb8..d797a784280 100644 --- a/mozilla/layout/generic/nsObjectFrame.cpp +++ b/mozilla/layout/generic/nsObjectFrame.cpp @@ -507,7 +507,11 @@ nsObjectFrame::DidReflow(nsIPresContext& aPresContext, GetOffsetFromView(origin, parentWithView); +#if 0 parentWithView->GetScrollOffset(&offx, &offy); +#else + offx = offy = 0; +#endif // window->x = NSTwipsToIntPixels(origin.x, t2p); // window->y = NSTwipsToIntPixels(origin.y, t2p); diff --git a/mozilla/layout/html/base/src/nsHTMLFrame.cpp b/mozilla/layout/html/base/src/nsHTMLFrame.cpp index cd26792d729..e5ddbd7ba40 100644 --- a/mozilla/layout/html/base/src/nsHTMLFrame.cpp +++ b/mozilla/layout/html/base/src/nsHTMLFrame.cpp @@ -36,6 +36,10 @@ #include "nsHTMLAtoms.h" #include "nsIEventStateManager.h" #include "nsIDeviceContext.h" +#include "nsIScrollableView.h" + +// Interface IDs +static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID); class RootFrame : public nsContainerFrame { public: @@ -60,6 +64,8 @@ class RootContentFrame : public nsContainerFrame { public: RootContentFrame(nsIContent* aContent, nsIFrame* aParent); + NS_IMETHOD DidReflow(nsIPresContext& aPresContext, + nsDidReflowStatus aStatus); NS_IMETHOD Reflow(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, @@ -258,15 +264,40 @@ RootContentFrame::RootContentFrame(nsIContent* aContent, nsIFrame* aParent) NS_ASSERTION(nsnull != viewManager, "null view manager"); view->Init(viewManager, mRect, rootView); - viewManager->InsertChild(rootView, view, 0); - NS_RELEASE(viewManager); + // We expect the root view to be a scrolling view + nsIScrollableView* scrollView; + if (NS_SUCCEEDED(rootView->QueryInterface(kScrollViewIID, (void**)&scrollView))) { + scrollView->SetScrolledView(view); + } + // Remember our view SetView(view); + + // Don't allow our view's position to be changed. It's controlled by the + // scrollview + mState &= ~NS_FRAME_SYNC_FRAME_AND_VIEW; } } +NS_IMETHODIMP +RootContentFrame::DidReflow(nsIPresContext& aPresContext, + nsDidReflowStatus aStatus) +{ + if (NS_FRAME_REFLOW_FINISHED == aStatus) { + // Size the view. Don't position it... + nsIView* view; + nsIViewManager *vm; + + GetView(view); + view->GetViewManager(vm); + vm->ResizeView(view, mRect.width, mRect.height); + NS_RELEASE(vm); + } + return nsContainerFrame::DidReflow(aPresContext, aStatus); +} + // Determine the margins to place around the child frame. Note that // this applies to the frame in the page-frame when paginating, not // to the page-frame. diff --git a/mozilla/layout/html/base/src/nsObjectFrame.cpp b/mozilla/layout/html/base/src/nsObjectFrame.cpp index 4b96b2b8fb8..d797a784280 100644 --- a/mozilla/layout/html/base/src/nsObjectFrame.cpp +++ b/mozilla/layout/html/base/src/nsObjectFrame.cpp @@ -507,7 +507,11 @@ nsObjectFrame::DidReflow(nsIPresContext& aPresContext, GetOffsetFromView(origin, parentWithView); +#if 0 parentWithView->GetScrollOffset(&offx, &offy); +#else + offx = offy = 0; +#endif // window->x = NSTwipsToIntPixels(origin.x, t2p); // window->y = NSTwipsToIntPixels(origin.y, t2p); diff --git a/mozilla/layout/html/base/src/nsScrollFrame.cpp b/mozilla/layout/html/base/src/nsScrollFrame.cpp index ee13316f449..5b33203fa7a 100644 --- a/mozilla/layout/html/base/src/nsScrollFrame.cpp +++ b/mozilla/layout/html/base/src/nsScrollFrame.cpp @@ -30,8 +30,12 @@ #include "nsIScrollableView.h" #include "nsWidgetsCID.h" -static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID); static NS_DEFINE_IID(kWidgetCID, NS_CHILD_CID); +static NS_DEFINE_IID(kScrollingViewCID, NS_SCROLLING_VIEW_CID); +static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID); + +static NS_DEFINE_IID(kViewCID, NS_VIEW_CID); +static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID); //---------------------------------------------------------------------- @@ -63,7 +67,7 @@ nsScrollViewFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) // Unless it's already a body frame, child frames that are containers // need to be wrapped in a body frame. - // XXX Check for it a;ready being a body frame... + // XXX Check for it already being a body frame... nsIFrame* wrapperFrame; if (CreateWrapperFrame(aPresContext, aChildList, wrapperFrame)) { mFirstChild = wrapperFrame; @@ -85,15 +89,6 @@ nsScrollViewFrame::Reflow(nsIPresContext& aPresContext, aReflowState.maxSize.width, aReflowState.maxSize.height)); - // Create a view - if (eReflowReason_Initial == aReflowState.reason) { - // XXX It would be nice if we could do this sort of thing in our Init() - // member function instead of here. Problem is the other frame code - // would have to do the same... - nsHTMLContainerFrame::CreateViewForFrame(aPresContext, this, - mStyleContext, PR_TRUE); - } - // Scroll frame handles the border, and we handle the padding and background const nsStyleSpacing* spacing = (const nsStyleSpacing*) mStyleContext->GetStyleData(eStyleStruct_Spacing); @@ -170,6 +165,9 @@ public: NS_IMETHOD Init(nsIPresContext& aPresContext, nsIFrame* aChildList); + NS_IMETHOD DidReflow(nsIPresContext& aPresContext, + nsDidReflowStatus aStatus); + NS_IMETHOD Reflow(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, @@ -183,6 +181,9 @@ public: protected: virtual PRIntn GetSkipSides() const; + +private: + nsresult CreateScrollingView(); }; nsScrollingViewFrame::nsScrollingViewFrame(nsIContent* aContent, nsIFrame* aParent) @@ -190,6 +191,38 @@ nsScrollingViewFrame::nsScrollingViewFrame(nsIContent* aContent, nsIFrame* aPare { } +NS_IMETHODIMP +nsScrollingViewFrame::DidReflow(nsIPresContext& aPresContext, + nsDidReflowStatus aStatus) +{ + nsresult rv = NS_OK; + + if (NS_FRAME_REFLOW_FINISHED == aStatus) { + // Send the DidReflow notification to the scrolled view frame + nsIHTMLReflow* htmlReflow; + + mFirstChild->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow); + htmlReflow->DidReflow(aPresContext, aStatus); + + // Size the scrolled view frame's view. Don't change its position + nsSize size; + nsIViewManager* vm; + nsIView* scrolledView; + + mFirstChild->GetSize(size); + mFirstChild->GetView(scrolledView); + scrolledView->GetViewManager(vm); + vm->ResizeView(scrolledView, size.width, size.height); + NS_RELEASE(vm); + + // Let the default nsFrame implementation clear the state flags + // and size and position our view + rv = nsFrame::DidReflow(aPresContext, aStatus); + } + + return rv; +} + NS_IMETHODIMP nsScrollingViewFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) { @@ -210,6 +243,92 @@ nsScrollingViewFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) return mFirstChild->Init(aPresContext, aChildList); } +nsresult +nsScrollingViewFrame::CreateScrollingView() +{ + nsIView* view; + + // Get parent view + nsIFrame* parent; + GetParentWithView(parent); + NS_ASSERTION(parent, "GetParentWithView failed"); + nsIView* parentView; + parent->GetView(parentView); + NS_ASSERTION(parentView, "GetParentWithView failed"); + + // Get the view manager + nsIViewManager* viewManager; + parentView->GetViewManager(viewManager); + + // Create the scrolling view + nsresult rv = nsRepository::CreateInstance(kScrollingViewCID, + nsnull, + kIViewIID, + (void **)&view); + + if (NS_OK == rv) { + // Get the native widget that should be used as the parent for + // the scrolling view's scrollbar child widgets. Note that we can't + // use the scrolling view's widget as the parent of the scrollbar + // widgets + nsIWidget* window; + nsNativeWidget nativeWidget; + GetWindow(window); + nativeWidget = window->GetNativeData(NS_NATIVE_WINDOW); + NS_RELEASE(window); + + // Initialize the scrolling view + view->Init(viewManager, mRect, parentView, &kWidgetCID, + nsnull, nativeWidget); + + // Insert the view into the view hierarchy + viewManager->InsertChild(parentView, view, 0); + + // If the background is transparent then inform the view manager + const nsStyleColor* color = (const nsStyleColor*) + mStyleContext->GetStyleData(eStyleStruct_Color); + + PRBool isTransparent = (NS_STYLE_BG_COLOR_TRANSPARENT & color->mBackgroundFlags); + if (isTransparent) { + viewManager->SetViewContentTransparency(view, PR_TRUE); + } + + // Remember our view + SetView(view); + + // Create a view for the scroll view frame + nsIView* scrolledView; + rv = nsRepository::CreateInstance(kViewCID, nsnull, kIViewIID, (void **)&scrolledView); + if (NS_OK == rv) { + // Bind the view to the frame + mFirstChild->SetView(scrolledView); + + // Initialize the view + scrolledView->Init(viewManager, nsRect(0, 0, 0, 0), parentView); + + // Set it as the scrolling view's scrolled view + nsIScrollableView* scrollingView; + view->QueryInterface(kScrollViewIID, (void**)&scrollingView); + scrollingView->SetScrolledView(scrolledView); + + // If the background is transparent then inform the view manager + if (isTransparent) { + viewManager->SetViewContentTransparency(scrolledView, PR_TRUE); + } + + // We need to allow the view's position to be different than the + // frame's position + nsFrameState state; + mFirstChild->GetFrameState(state); + state &= ~NS_FRAME_SYNC_FRAME_AND_VIEW; + mFirstChild->SetFrameState(state); + } + } + + NS_RELEASE(viewManager); + return rv; +} + //XXX incremental reflow pass through NS_IMETHODIMP nsScrollingViewFrame::Reflow(nsIPresContext& aPresContext, @@ -222,63 +341,9 @@ nsScrollingViewFrame::Reflow(nsIPresContext& aPresContext, aReflowState.maxSize.width, aReflowState.maxSize.height)); - // Make sure we have a scrolling view - nsIView* view; - GetView(view); - if (nsnull == view) { - static NS_DEFINE_IID(kScrollingViewCID, NS_SCROLLING_VIEW_CID); - static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID); - - // Get parent view - nsIFrame* parent; - GetParentWithView(parent); - NS_ASSERTION(parent, "GetParentWithView failed"); - nsIView* parentView; - parent->GetView(parentView); - NS_ASSERTION(parentView, "GetParentWithView failed"); - - nsIViewManager* viewManager; - parentView->GetViewManager(viewManager); - - nsresult rv = nsRepository::CreateInstance(kScrollingViewCID, - nsnull, - kIViewIID, - (void **)&view); - - // Get the native widget that should be used as the parent for - // the scrolling view's scrollbar child widgets. Note that we can't - // use the scrolling view's widget as the parent of the scrollbar - // widgets - nsIWidget* window; - nsNativeWidget nativeWidget; - GetWindow(window); - nativeWidget = window->GetNativeData(NS_NATIVE_WINDOW); - NS_RELEASE(window); - - if ((NS_OK != rv) || (NS_OK != view->Init(viewManager, - mRect, - parentView, - &kWidgetCID, - nsnull, - nativeWidget))) { - NS_RELEASE(viewManager); - return rv; - } - - // Insert new view as a child of the parent view - viewManager->InsertChild(parentView, view, 0); - - // If the background is transparent then inform the view manager - const nsStyleColor* color = (const nsStyleColor*) - mStyleContext->GetStyleData(eStyleStruct_Color); - if (NS_STYLE_BG_COLOR_TRANSPARENT & color->mBackgroundFlags) { - viewManager->SetViewContentTransparency(view, PR_TRUE); - } - SetView(view); - NS_RELEASE(viewManager); - } - if (nsnull == view) { - return NS_OK; + // If it's out initial reflow then create a scrolling view + if (eReflowReason_Initial == aReflowState.reason) { + CreateScrollingView(); } // Reflow the child and get its desired size. Let the child's height be diff --git a/mozilla/view/public/nsIScrollableView.h b/mozilla/view/public/nsIScrollableView.h index 431465e2d63..57712e5b141 100644 --- a/mozilla/view/public/nsIScrollableView.h +++ b/mozilla/view/public/nsIScrollableView.h @@ -52,19 +52,10 @@ public: NS_IMETHOD GetContainerSize(nscoord *aWidth, nscoord *aHeight) = 0; /** - * Set the offset into the container of the - * top/left most visible coordinate - * @param aOffsetX X offset in twips - * @param aOffsetY Y offset in twips + * Set the view that we are scrolling within the + * scrolling view. */ - NS_IMETHOD SetVisibleOffset(nscoord aOffsetX, nscoord aOffsetY) = 0; - - /** - * Get the offset of the top/left most visible coordinate - * @param aOffsetX return value for X coordinate in twips - * @param aOffsetY return value for Y coordinate in twips - */ - NS_IMETHOD GetVisibleOffset(nscoord *aOffsetX, nscoord *aOffsetY) = 0; + NS_IMETHOD SetScrolledView(nsIView *aScrolledView) = 0; /** * Get the view that we are scrolling within the diff --git a/mozilla/view/public/nsIView.h b/mozilla/view/public/nsIView.h index 3c464c8203e..263305ab4f5 100644 --- a/mozilla/view/public/nsIView.h +++ b/mozilla/view/public/nsIView.h @@ -386,13 +386,6 @@ public: */ NS_IMETHOD GetOffsetFromWidget(nscoord *aDx, nscoord *aDy, nsIWidget *&aWidget) = 0; - /** - * Get the visible offset of scrollable view (if any) that contains this view - * @param aDx out parameter for x offset - * @param aDy out parameter for y offset - */ - NS_IMETHOD GetScrollOffset(nscoord *aDx, nscoord *aDy) = 0; - /** * Gets the dirty region associated with this view. Used by the view * manager. diff --git a/mozilla/view/public/nsIViewManager.h b/mozilla/view/public/nsIViewManager.h index 9b7a186d8c4..e16933912a7 100644 --- a/mozilla/view/public/nsIViewManager.h +++ b/mozilla/view/public/nsIViewManager.h @@ -99,14 +99,6 @@ public: */ NS_IMETHOD SetWindowDimensions(nscoord width, nscoord height) = 0; - /** - * Get the position of the window relative to the composited - * area. This indicates the scrolled position of the window. - * @param xoffset out parameter for X scroll position of window in twips - * @param yoffset out parameter for Y scroll position of window in twips - */ - NS_IMETHOD GetWindowOffsets(nsIView *aView, nscoord *xoffset, nscoord *yoffset) const = 0; - /** * Reset the state of scrollbars and the scrolling region */ diff --git a/mozilla/view/src/nsScrollingView.cpp b/mozilla/view/src/nsScrollingView.cpp index 00a6f8c9e48..3357e0113e2 100644 --- a/mozilla/view/src/nsScrollingView.cpp +++ b/mozilla/view/src/nsScrollingView.cpp @@ -243,14 +243,9 @@ NS_IMETHODIMP CornerView :: Paint(nsIRenderingContext& rc, const nsRect& rect, if (mVis == nsViewVisibility_kShow) { - nscoord xoff, yoff; nsRect brect; rc.PushState(); - - GetScrollOffset(&xoff, &yoff); - rc.Translate(xoff, yoff); - GetBounds(brect); clipres = rc.SetClipRect(brect, nsClipCombine_kIntersect); @@ -323,12 +318,7 @@ NS_IMETHODIMP CornerView :: Paint(nsIRenderingContext& rc, const nsRect& rect, if (clipres == PR_FALSE) { - nsRect xrect = brect; - - xrect.x += xoff; - xrect.y += yoff; - - clipres = rc.SetClipRect(xrect, nsClipCombine_kSubtract); + clipres = rc.SetClipRect(brect, nsClipCombine_kSubtract); } } @@ -342,6 +332,7 @@ nsScrollingView :: nsScrollingView() { mSizeX = mSizeY = 0; mOffsetX = mOffsetY = 0; + mClipView = nsnull; mVScrollBarView = nsnull; mHScrollBarView = nsnull; mCornerView = nsnull; @@ -364,9 +355,13 @@ nsScrollingView :: ~nsScrollingView() ((ScrollBarView*)mHScrollBarView)->mScrollingView = nsnull; } - if (nsnull != mCornerView) + mClipView = nsnull; + mCornerView = nsnull; + + if (nsnull != mScrollingTimer) { - mCornerView = nsnull; + mScrollingTimer->Cancel(); + NS_RELEASE(mScrollingTimer); } } @@ -421,8 +416,16 @@ NS_IMETHODIMP nsScrollingView :: Init(nsIViewManager* aManager, nsIDeviceContext *dx; mViewManager->GetDeviceContext(dx); - // Create a view for a corner cover + // Create a clip view + mClipView = new nsView; + if (nsnull != mClipView) + { + rv = mClipView->Init(mViewManager, aBounds, this, nsnull, nsnull, nsnull, -1, nsnull, aOpacity); + mViewManager->InsertChild(this, mClipView, -1); + } + + // Create a view for a corner cover mCornerView = new CornerView; if (nsnull != mCornerView) @@ -539,6 +542,11 @@ NS_IMETHODIMP nsScrollingView :: SetDimensions(nscoord width, nscoord height, PR mClipY = height; } + if (nsnull != mClipView) + { + mClipView->SetDimensions(width - showVert, height - showHorz); + } + if (nsnull != mVScrollBarView) { mVScrollBarView->GetDimensions(&trect.width, &trect.height); @@ -627,7 +635,9 @@ NS_IMETHODIMP nsScrollingView :: Paint(nsIRenderingContext& rc, const nsRect& re if (clipres == PR_FALSE) { +#if 0 rc.Translate(-mOffsetX, -mOffsetY); +#endif nsView::Paint(rc, rect, aPaintFlags | NS_VIEW_FLAG_CLIP_SET, clipres); } @@ -677,14 +687,12 @@ void nsScrollingView :: HandleScrollEvent(nsGUIEvent *aEvent, PRUint32 aEventFla if (dy != 0) { - nscoord sx, sy; - - mVScrollBarView->GetDimensions(&sx, &sy); - - if ((nsnull != mHScrollBarView) && ViewIsShowing(mHScrollBarView)) - mHScrollBarView->GetDimensions(&sx, &sy); - else - sy = 0; + // Slide the scrolled view + nsIView *scrolledView; + nscoord x, y; + GetScrolledView(scrolledView); + scrolledView->GetPosition(&x, &y); + scrolledView->SetPosition(x, -mOffsetY); // XXX Clearing everything isn't correct, but maybe we should clear it for // our view... @@ -747,14 +755,12 @@ void nsScrollingView :: HandleScrollEvent(nsGUIEvent *aEvent, PRUint32 aEventFla if (dx != 0) { - nscoord sx, sy; - - if ((nsnull != mVScrollBarView) && ViewIsShowing(mVScrollBarView)) - mVScrollBarView->GetDimensions(&sx, &sy); - else - sx = 0; - - mHScrollBarView->GetDimensions(&sx, &sy); + // Slide the scrolled view + nsIView *scrolledView; + nscoord x, y; + GetScrolledView(scrolledView); + scrolledView->GetPosition(&x, &y); + scrolledView->SetPosition(-mOffsetX, y); // XXX Clearing everything isn't correct, but maybe we should clear it for // our view... @@ -804,8 +810,8 @@ void nsScrollingView :: Notify(nsITimer * aTimer) GetScrolledView(view); // First do the scrolling of the view - - view->GetScrollOffset(&xoff, &yoff); + xoff = mOffsetX; + yoff = mOffsetY; nscoord newPos = yoff + mScrollingDelta; @@ -931,6 +937,8 @@ nsIWidget *win; GetBounds(brect); + // XXX Huh. We shouldn't just be doing this for any mouse move. + // If this is for auto-scrolling then only on mouse press and drag... lx = aEvent->point.x - (brect.x); ly = aEvent->point.y - (brect.y); @@ -999,18 +1007,7 @@ nsIWidget *win; if (NS_OK == mViewManager->GetViewObserver(obs)) { - nscoord xoff, yoff; - - GetScrollOffset(&xoff, &yoff); - - aEvent->point.x += xoff; - aEvent->point.y += yoff; - obs->HandleEvent((nsIView *)this, aEvent, retval); - - aEvent->point.x -= xoff; - aEvent->point.y -= yoff; - NS_RELEASE(obs); } } @@ -1027,12 +1024,12 @@ nsIWidget *win; NS_IMETHODIMP nsScrollingView :: ComputeContainerSize() { - nsIView *scrollview; - GetScrolledView(scrollview); + nsIView *scrolledView; + GetScrolledView(scrolledView); nsIScrollbar *scrollv = nsnull, *scrollh = nsnull; nsIWidget *win; - if (nsnull != scrollview) + if (nsnull != scrolledView) { nscoord dx = 0, dy = 0; nsIDeviceContext *px; @@ -1046,10 +1043,14 @@ NS_IMETHODIMP nsScrollingView :: ComputeContainerSize() mViewManager->GetDeviceContext(px); px->GetAppUnitsToDevUnits(scale); - ComputeScrollArea(scrollview, area, 0, 0); +#if 0 + ComputeScrollArea(scrolledView, area, 0, 0); mSizeY = area.YMost(); mSizeX = area.XMost(); +#else + scrolledView->GetDimensions(&mSizeX, &mSizeY); +#endif if (nsnull != mHScrollBarView) { @@ -1184,6 +1185,9 @@ NS_IMETHODIMP nsScrollingView :: ComputeContainerSize() NS_RELEASE(win); } + // Position the scrolled view + scrolledView->SetPosition(-mOffsetX, -mOffsetY); + if (mCornerView) { if (mHScrollBarView && ViewIsShowing(mHScrollBarView) && @@ -1250,20 +1254,6 @@ NS_IMETHODIMP nsScrollingView :: GetContainerSize(nscoord *aWidth, nscoord *aHei return NS_OK; } -NS_IMETHODIMP nsScrollingView :: SetVisibleOffset(nscoord aOffsetX, nscoord aOffsetY) -{ - mOffsetX = aOffsetX; - mOffsetY = aOffsetY; - return NS_OK; -} - -NS_IMETHODIMP nsScrollingView :: GetVisibleOffset(nscoord *aOffsetX, nscoord *aOffsetY) -{ - *aOffsetX = mOffsetX; - *aOffsetY = mOffsetY; - return NS_OK; -} - NS_IMETHODIMP nsScrollingView :: ShowQuality(PRBool aShow) { ((CornerView *)mCornerView)->ShowQuality(aShow); @@ -1343,16 +1333,21 @@ nsScrollingView :: ScrollTo(nscoord aX, nscoord aY, PRUint32 aUpdateFlags) dy = oldpos - newpos; - // Update offsets - SetVisibleOffset(aX, aY); + // Update the scrolled view's position + nsIView* scrolledView; + GetScrolledView(scrolledView); + if (nsnull != scrolledView) + { + scrolledView->SetPosition(-aX, -aY); + mOffsetX = aX; + mOffsetY = aY; + } AdjustChildWidgets(this, this, 0, 0, t2p); // Damage the updated area r.x = 0; r.y = aY; - nsIView* scrolledView; - GetScrolledView(scrolledView); if (nsnull != scrolledView) { mViewManager->UpdateView(scrolledView, r, aUpdateFlags); @@ -1385,33 +1380,6 @@ void nsScrollingView :: AdjustChildWidgets(nsScrollingView *aScrolling, nsIView { nsIWidget *widget; aScrolling->GetOffsetFromWidget(&aDx, &aDy, widget); - nsIView *parview; - aScrolling->GetParent(parview); - - while (nsnull != parview) - { - nsIWidget *parwidget; - parview->GetWidget(parwidget); - - if (NS_OK == parview->QueryInterface(kIScrollableViewIID, (void **)&scroller)) - { - scroller->GetVisibleOffset(&offx, &offy); - - aDx -= offx; - aDy -= offy; - } - - if (parwidget == widget) - { - NS_IF_RELEASE(parwidget); - break; - } - - NS_IF_RELEASE(parwidget); - - parview->GetParent(parview); - } - NS_IF_RELEASE(widget); } @@ -1420,16 +1388,6 @@ void nsScrollingView :: AdjustChildWidgets(nsScrollingView *aScrolling, nsIView aDx += offx; aDy += offy; - if (NS_OK == aView->QueryInterface(kIScrollableViewIID, (void **)&scroller)) - { - scroller->GetVisibleOffset(&offx, &offy); - - aDx -= offx; - aDy -= offy; - - isscroll = PR_TRUE; - } - for (PRInt32 cnt = 0; cnt < numkids; cnt++) { nsIView *kid; @@ -1463,26 +1421,14 @@ void nsScrollingView :: AdjustChildWidgets(nsScrollingView *aScrolling, nsIView } } +NS_IMETHODIMP nsScrollingView :: SetScrolledView(nsIView *aScrolledView) +{ + return mViewManager->InsertChild(mClipView, aScrolledView, 0); +} + NS_IMETHODIMP nsScrollingView :: GetScrolledView(nsIView *&aScrolledView) { - PRInt32 numkids; - - aScrolledView = nsnull; - GetChildCount(numkids); - - for (PRInt32 cnt = 0; cnt < numkids; cnt++) - { - GetChild(cnt, aScrolledView); - - if ((aScrolledView != mVScrollBarView) && - (aScrolledView != mHScrollBarView) && - (aScrolledView != mCornerView)) - break; - else - aScrolledView = nsnull; - } - - return NS_OK; + return mClipView->GetChild(0, aScrolledView); } void nsScrollingView :: ComputeScrollArea(nsIView *aView, nsRect &aRect, diff --git a/mozilla/view/src/nsScrollingView.h b/mozilla/view/src/nsScrollingView.h index 560fa4e50c0..987226a27c9 100644 --- a/mozilla/view/src/nsScrollingView.h +++ b/mozilla/view/src/nsScrollingView.h @@ -56,8 +56,12 @@ public: //nsIScrollableView interface NS_IMETHOD ComputeContainerSize(); NS_IMETHOD GetContainerSize(nscoord *aWidth, nscoord *aHeight); + // XXX TROY +#if 0 NS_IMETHOD SetVisibleOffset(nscoord aOffsetX, nscoord aOffsetY); NS_IMETHOD GetVisibleOffset(nscoord *aOffsetX, nscoord *aOffsetY); +#endif + NS_IMETHOD SetScrolledView(nsIView *aScrolledView); NS_IMETHOD GetScrolledView(nsIView *&aScrolledView); NS_IMETHOD ShowQuality(PRBool aShow); @@ -88,6 +92,7 @@ protected: protected: nscoord mSizeX, mSizeY; nscoord mOffsetX, mOffsetY; + nsIView *mClipView; nsIView *mVScrollBarView; nsIView *mHScrollBarView; nsIView *mCornerView; diff --git a/mozilla/view/src/nsView.cpp b/mozilla/view/src/nsView.cpp index c9dfb807283..f69db01994f 100644 --- a/mozilla/view/src/nsView.cpp +++ b/mozilla/view/src/nsView.cpp @@ -651,15 +651,11 @@ NS_IMETHODIMP nsView :: HandleEvent(nsGUIEvent *event, PRUint32 aEventFlags, for (PRInt32 cnt = 0; cnt < numkids; cnt++) { nsIView *pKid; - nscoord lx, ly; GetChild(cnt, pKid); pKid->GetBounds(trect); - lx = x - trect.x; - ly = y - trect.y; - - if (trect.Contains(lx, ly)) + if (trect.Contains(x, y)) { //the x, y position of the event in question //is inside this child view, so give it the @@ -686,18 +682,7 @@ NS_IMETHODIMP nsView :: HandleEvent(nsGUIEvent *event, PRUint32 aEventFlags, if (NS_OK == mViewManager->GetViewObserver(obs)) { - nscoord xoff, yoff; - - GetScrollOffset(&xoff, &yoff); - - event->point.x += xoff; - event->point.y += yoff; - obs->HandleEvent((nsIView *)this, event, aStatus); - - event->point.x -= xoff; - event->point.y -= yoff; - NS_RELEASE(obs); } } @@ -712,22 +697,19 @@ NS_IMETHODIMP nsView :: SetPosition(nscoord x, nscoord y) if (nsnull != mWindow) { nsIDeviceContext *dx; - nscoord offx, offy, parx = 0, pary = 0; float scale; nsIWidget *pwidget = nsnull; + nscoord parx = 0, pary = 0; mViewManager->GetDeviceContext(dx); dx->GetAppUnitsToDevUnits(scale); - - GetScrollOffset(&offx, &offy); + NS_RELEASE(dx); GetOffsetFromWidget(&parx, &pary, pwidget); NS_IF_RELEASE(pwidget); - mWindow->Move(NSTwipsToIntPixels((x + parx - offx), scale), - NSTwipsToIntPixels((y + pary - offy), scale)); - - NS_RELEASE(dx); + mWindow->Move(NSTwipsToIntPixels((x + parx), scale), + NSTwipsToIntPixels((y + pary), scale)); } return NS_OK; @@ -760,7 +742,13 @@ NS_IMETHODIMP nsView :: SetDimensions(nscoord width, nscoord height, PRBool aPai static NS_DEFINE_IID(kscroller, NS_ISCROLLABLEVIEW_IID); - if (NS_OK == mParent->QueryInterface(kscroller, (void **)&scroller)) + // XXX The scrolled view is a child of the clip view which is a child of + // the scrolling view. It's kind of yucky the way this works. A parent + // notification that the child's size changed would be cleaner. + nsIView *grandParent; + mParent->GetParent(grandParent); + if ((nsnull != grandParent) && + (NS_OK == grandParent->QueryInterface(kscroller, (void **)&scroller))) { scroller->ComputeContainerSize(); } @@ -1051,18 +1039,11 @@ NS_IMETHODIMP nsView :: GetClientData(void *&aData) // nsresult nsView :: LoadWidget(const nsCID &aClassIID) { - nsISupports* window; - nsresult rv; - - static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); - rv = nsRepository::CreateInstance(aClassIID, nsnull, kISupportsIID, (void**)&window); + nsresult rv; + static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID); + rv = nsRepository::CreateInstance(aClassIID, nsnull, kIWidgetIID, (void**)&mWindow); if (NS_OK == rv) { - // get a pointer to the nsIWidget* interface - static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID); - rv = window->QueryInterface(kIWidgetIID, (void**)&mWindow); - window->Release(); - // Set the widget's client data mWindow->SetClientData((void*)this); } @@ -1128,31 +1109,6 @@ NS_IMETHODIMP nsView :: GetOffsetFromWidget(nscoord *aDx, nscoord *aDy, nsIWidge return NS_OK; } -NS_IMETHODIMP nsView :: GetScrollOffset(nscoord *aDx, nscoord *aDy) -{ - nsIWidget *window = nsnull; - nsIView *ancestor; - - GetParent(ancestor); - while (nsnull != ancestor) - { - nsIScrollableView *sview; - - static NS_DEFINE_IID(kscroller, NS_ISCROLLABLEVIEW_IID); - - if (NS_OK == ancestor->QueryInterface(kscroller, (void **)&sview)) - { - sview->GetVisibleOffset(aDx, aDy); - return NS_OK; - } - - ancestor->GetParent(ancestor); - } - - *aDx = *aDy = 0; - return NS_OK; -} - NS_IMETHODIMP nsView :: GetDirtyRegion(nsIRegion *&aRegion) { aRegion = mDirtyRegion; diff --git a/mozilla/view/src/nsView.h b/mozilla/view/src/nsView.h index efc8bf66db2..19573dab9e2 100644 --- a/mozilla/view/src/nsView.h +++ b/mozilla/view/src/nsView.h @@ -94,7 +94,10 @@ public: NS_IMETHOD SetClientData(void *aData); NS_IMETHOD GetClientData(void *&aData); NS_IMETHOD GetOffsetFromWidget(nscoord *aDx, nscoord *aDy, nsIWidget *&aWidget); + // XXX TROY +#if 0 NS_IMETHOD GetScrollOffset(nscoord *aDx, nscoord *aDy); +#endif NS_IMETHOD GetDirtyRegion(nsIRegion*& aRegion); NS_IMETHOD SetDirtyRegion(nsIRegion* aRegion); virtual void List(FILE* out = stdout, PRInt32 aIndent = 0) const; diff --git a/mozilla/view/src/nsViewManager.cpp b/mozilla/view/src/nsViewManager.cpp index 11058cdf6ca..d4ee4bbbbdf 100644 --- a/mozilla/view/src/nsViewManager.cpp +++ b/mozilla/view/src/nsViewManager.cpp @@ -236,22 +236,6 @@ NS_IMETHODIMP nsViewManager :: SetWindowDimensions(nscoord width, nscoord height return NS_OK; } -NS_IMETHODIMP nsViewManager :: GetWindowOffsets(nsIView *aView, nscoord *xoffset, nscoord *yoffset) const -{ - if (nsnull != mRootView) - { - nsIScrollableView *scroller; - - if (NS_OK == aView->QueryInterface(kIScrollableViewIID, (void **)&scroller)) - scroller->GetVisibleOffset(xoffset, yoffset); - else - *xoffset = *yoffset = 0; - } - else - *xoffset = *yoffset = 0; - return NS_OK; -} - NS_IMETHODIMP nsViewManager :: ResetScrolling(void) { if (nsnull != mRootView) @@ -274,7 +258,6 @@ void nsViewManager :: Refresh(nsIView *aView, nsIRenderingContext *aContext, nsI { nsRect wrect; nsIRenderingContext *localcx = nsnull; - nscoord xoff, yoff; float scale; if (PR_FALSE == mRefreshEnabled) @@ -316,12 +299,7 @@ void nsViewManager :: Refresh(nsIView *aView, nsIRenderingContext *aContext, nsI mContext->GetAppUnitsToDevUnits(scale); - GetWindowOffsets(aView, &xoff, &yoff); - - region->Offset(NSTwipsToIntPixels(-xoff, scale), NSTwipsToIntPixels(-yoff, scale)); -// localcx->SetClipRegion(*region, nsClipCombine_kIntersect); localcx->SetClipRegion(*region, nsClipCombine_kReplace); - region->Offset(NSTwipsToIntPixels(xoff, scale), NSTwipsToIntPixels(yoff, scale)); nsRect trect; float p2t; @@ -361,7 +339,6 @@ void nsViewManager :: Refresh(nsIView *aView, nsIRenderingContext *aContext, con { nsRect wrect; nsIRenderingContext *localcx = nsnull; - nscoord xoff, yoff; if (PR_FALSE == mRefreshEnabled) return; @@ -402,11 +379,8 @@ void nsViewManager :: Refresh(nsIView *aView, nsIRenderingContext *aContext, con localcx->SelectOffScreenDrawingSurface(ds); } - GetWindowOffsets(aView, &xoff, &yoff); - nsRect trect = *rect; - trect.MoveBy(-xoff, -yoff); localcx->SetClipRect(trect, nsClipCombine_kReplace); PRBool result; @@ -548,13 +522,6 @@ NS_IMETHODIMP nsViewManager :: UpdateView(nsIView *aView, const nsRect &aRect, P while ((nsnull != par) && (par != widgetView)); } - nscoord xoffset, yoffset; - GetWindowOffsets(widgetView, &xoffset, &yoffset); - trect.MoveBy(-xoffset, -yoffset); - if (trect.y < 0) { - trect.y = 0; - } - // Add this rect to the widgetView's dirty region. AddRectToDirtyRegion(widgetView, trect); @@ -648,10 +615,6 @@ NS_IMETHODIMP nsViewManager :: DispatchEvent(nsGUIEvent *aEvent, nsEventStatus & mContext->GetDevUnitsToAppUnits(p2t); trect.ScaleRoundOut(p2t); - nscoord xoffset, yoffset; - GetWindowOffsets(view, &xoffset, &yoffset); - trect.MoveBy(xoffset, yoffset); - // Add the rect to the existing dirty region AddRectToDirtyRegion(view, trect); diff --git a/mozilla/view/src/nsViewManager.h b/mozilla/view/src/nsViewManager.h index b4eff710a7e..a2cb05ef5aa 100644 --- a/mozilla/view/src/nsViewManager.h +++ b/mozilla/view/src/nsViewManager.h @@ -50,8 +50,6 @@ public: NS_IMETHOD GetWindowDimensions(nscoord *width, nscoord *height); NS_IMETHOD SetWindowDimensions(nscoord width, nscoord height); - NS_IMETHOD GetWindowOffsets(nsIView *aView, nscoord *xoffset, nscoord *yoffset) const; - NS_IMETHOD ResetScrolling(void); NS_IMETHOD Composite(void);