зеркало из https://github.com/mozilla/gecko-dev.git
form elements, etc. (i.e. sub widgets) now scroll smoothly.
This commit is contained in:
Родитель
cb77901bc4
Коммит
404c0a78e4
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче