зеркало из https://github.com/mozilla/gecko-dev.git
made form elements scroll smoothly. added apis to widgets to support this.
This commit is contained in:
Родитель
51dcc96d82
Коммит
936ee3ae67
|
@ -299,7 +299,11 @@ nsEventStatus nsScrollingView :: HandleEvent(nsGUIEvent *aEvent, PRUint32 aEvent
|
|||
clip.height = NS_TO_INT_ROUND(scale * (mBounds.height - sy));
|
||||
|
||||
mViewManager->ClearDirtyRegion();
|
||||
mWindow->Scroll(0, dy, &clip);
|
||||
|
||||
nsIWidget *thiswin = GetWidget();
|
||||
|
||||
if (nsnull != thiswin)
|
||||
thiswin->BeginResizingChildren();
|
||||
|
||||
//and now we make sure that the scrollbar thumb is in sync with the
|
||||
//numbers we came up with here, but only if we actually moved at least
|
||||
|
@ -307,6 +311,18 @@ nsEventStatus nsScrollingView :: HandleEvent(nsGUIEvent *aEvent, PRUint32 aEvent
|
|||
//very slow scrolling would never actually work.
|
||||
|
||||
((nsScrollbarEvent *)aEvent)->position = mOffsetY;
|
||||
|
||||
if (dy != 0)
|
||||
{
|
||||
AdjustChildWidgets(0, dy);
|
||||
mWindow->Scroll(0, dy, &clip);
|
||||
}
|
||||
|
||||
if (nsnull != thiswin)
|
||||
{
|
||||
thiswin->EndResizingChildren();
|
||||
NS_RELEASE(thiswin);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((nsnull != mHScrollBarView) && (scview == mHScrollBarView))
|
||||
|
@ -344,7 +360,11 @@ nsEventStatus nsScrollingView :: HandleEvent(nsGUIEvent *aEvent, PRUint32 aEvent
|
|||
clip.height = NS_TO_INT_ROUND(scale * (mBounds.height - sy));
|
||||
|
||||
mViewManager->ClearDirtyRegion();
|
||||
mWindow->Scroll(dx, 0, &clip);
|
||||
|
||||
nsIWidget *thiswin = GetWidget();
|
||||
|
||||
if (nsnull != thiswin)
|
||||
thiswin->BeginResizingChildren();
|
||||
|
||||
//and now we make sure that the scrollbar thumb is in sync with the
|
||||
//numbers we came up with here, but only if we actually moved at least
|
||||
|
@ -352,12 +372,21 @@ nsEventStatus nsScrollingView :: HandleEvent(nsGUIEvent *aEvent, PRUint32 aEvent
|
|||
//very slow scrolling would never actually work.
|
||||
|
||||
((nsScrollbarEvent *)aEvent)->position = mOffsetX;
|
||||
|
||||
if (dx != 0)
|
||||
{
|
||||
AdjustChildWidgets(dx, 0);
|
||||
mWindow->Scroll(dx, 0, &clip);
|
||||
}
|
||||
|
||||
if (nsnull != thiswin)
|
||||
{
|
||||
thiswin->EndResizingChildren();
|
||||
NS_RELEASE(thiswin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((dx != 0) || (dy != 0))
|
||||
AdjustChildWidgets(dx, dy);
|
||||
|
||||
retval = nsEventStatus_eConsumeNoDefault;
|
||||
|
||||
NS_RELEASE(px);
|
||||
|
@ -388,6 +417,7 @@ void nsScrollingView :: ComputeContainerSize()
|
|||
nscoord dx = 0, dy = 0;
|
||||
nsIPresContext *px = mViewManager->GetPresContext();
|
||||
nscoord width, height;
|
||||
nscoord vwidth, vheight;
|
||||
PRUint32 oldsizey = mSizeY, oldsizex = mSizeX;
|
||||
nsRect area(0, 0, 0, 0);
|
||||
nscoord offx, offy;
|
||||
|
@ -400,7 +430,7 @@ void nsScrollingView :: ComputeContainerSize()
|
|||
|
||||
if (nsnull != mVScrollBarView)
|
||||
{
|
||||
mVScrollBarView->GetDimensions(&width, &height);
|
||||
mVScrollBarView->GetDimensions(&vwidth, &vheight);
|
||||
offy = mOffsetY;
|
||||
|
||||
win = mVScrollBarView->GetWidget();
|
||||
|
@ -430,7 +460,8 @@ void nsScrollingView :: ComputeContainerSize()
|
|||
mVScrollBarView->SetVisibility(nsViewVisibility_kHide);
|
||||
}
|
||||
|
||||
NS_RELEASE(scrollv);
|
||||
//don't release the vertical scroller here because if we need to
|
||||
//create a horizontal one, it will need to tweak the vertical one
|
||||
}
|
||||
|
||||
NS_RELEASE(win);
|
||||
|
@ -459,7 +490,13 @@ void nsScrollingView :: ComputeContainerSize()
|
|||
|
||||
dx = NS_TO_INT_ROUND(scale * (offx - mOffsetX));
|
||||
|
||||
scrollh->SetParameters(mSizeX, mBounds.width, mOffsetX, NS_POINTS_TO_TWIPS_INT(12));
|
||||
scrollh->SetParameters(mSizeX, mBounds.width - ((nsnull != scrollv) ? vwidth : 0),
|
||||
mOffsetX, NS_POINTS_TO_TWIPS_INT(12));
|
||||
|
||||
//now make the vertical scroll region account for this scrollbar
|
||||
|
||||
if (nsnull != scrollv)
|
||||
scrollv->SetParameters(mSizeY, mBounds.height - height, mOffsetY, NS_POINTS_TO_TWIPS_INT(12));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -474,6 +511,10 @@ void nsScrollingView :: ComputeContainerSize()
|
|||
NS_RELEASE(win);
|
||||
}
|
||||
|
||||
// now we can release the vertical srcoller if there was one...
|
||||
|
||||
NS_IF_RELEASE(scrollv);
|
||||
|
||||
if ((dx != 0) || (dy != 0))
|
||||
AdjustChildWidgets(dx, dy);
|
||||
|
||||
|
@ -537,7 +578,7 @@ void nsScrollingView :: GetVisibleOffset(nscoord *aOffsetX, nscoord *aOffsetY)
|
|||
|
||||
void nsScrollingView :: AdjustChildWidgets(nscoord aDx, nscoord aDy)
|
||||
{
|
||||
PRInt32 numkids = GetChildCount();
|
||||
PRInt32 numkids = GetChildCount();
|
||||
|
||||
for (PRInt32 cnt = 0; cnt < numkids; cnt++)
|
||||
{
|
||||
|
@ -551,13 +592,18 @@ void nsScrollingView :: AdjustChildWidgets(nscoord aDx, nscoord aDy)
|
|||
{
|
||||
nsRect bounds;
|
||||
|
||||
win->BeginResizingChildren();
|
||||
win->GetBounds(bounds);
|
||||
win->Move(bounds.x + aDx, bounds.y + aDy);
|
||||
|
||||
NS_RELEASE(win);
|
||||
}
|
||||
|
||||
kid->AdjustChildWidgets(aDx, aDy);
|
||||
|
||||
if (nsnull != win)
|
||||
{
|
||||
win->EndResizingChildren();
|
||||
NS_RELEASE(win);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -877,12 +877,17 @@ void nsView :: AdjustChildWidgets(nscoord aDx, nscoord aDy)
|
|||
{
|
||||
nsRect bounds;
|
||||
|
||||
win->BeginResizingChildren();
|
||||
win->GetBounds(bounds);
|
||||
win->Move(bounds.x + aDx, bounds.y + aDy);
|
||||
|
||||
NS_RELEASE(win);
|
||||
}
|
||||
|
||||
kid->AdjustChildWidgets(aDx, aDy);
|
||||
|
||||
if (nsnull != win)
|
||||
{
|
||||
win->EndResizingChildren();
|
||||
NS_RELEASE(win);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -433,6 +433,23 @@ class nsIWidget : public nsISupports {
|
|||
|
||||
virtual void ScreenToWidget(const nsRect& aOldRect, nsRect& aNewRect) = 0;
|
||||
|
||||
/**
|
||||
* When adjustments are to made to a whole set of child widgets, call this
|
||||
* before resizing/positioning the child windows to minimize repaints. Must
|
||||
* be followed by EndResizingChildren() after child windows have been
|
||||
* adjusted.
|
||||
*
|
||||
*/
|
||||
|
||||
virtual void BeginResizingChildren(void) = 0;
|
||||
|
||||
/**
|
||||
* Call this when finished adjusting child windows. Must be preceded by
|
||||
* BeginResizingChildren().
|
||||
*
|
||||
*/
|
||||
|
||||
virtual void EndResizingChildren(void) = 0;
|
||||
};
|
||||
|
||||
#endif // nsIWidget_h__
|
||||
|
|
|
@ -42,7 +42,27 @@ extern HINSTANCE g_hinst;
|
|||
static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID);
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// Deferred Window positioning
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
void nsWindow::BeginResizingChildren(void)
|
||||
{
|
||||
if (NULL == mDeferredPositioner)
|
||||
mDeferredPositioner = ::BeginDeferWindowPos(1);
|
||||
//printf("begin defer on %x, parent %x\n", mWnd, ::GetParent(mWnd));
|
||||
}
|
||||
|
||||
void nsWindow::EndResizingChildren(void)
|
||||
{
|
||||
if (NULL != mDeferredPositioner) {
|
||||
//printf("end defer on %x, parent %x\n", mWnd, ::GetParent(mWnd));
|
||||
::EndDeferWindowPos(mDeferredPositioner);
|
||||
mDeferredPositioner = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// DoCreateTooltip - creates a tooltip control and adds some tools
|
||||
// to it.
|
||||
|
@ -313,6 +333,7 @@ nsWindow::nsWindow(nsISupports *aOuter) : nsObject(aOuter)
|
|||
mIsAltDown = PR_FALSE;
|
||||
mIsDestroying = PR_FALSE;
|
||||
mTooltip = NULL;
|
||||
mDeferredPositioner = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -556,6 +577,11 @@ void nsWindow::Destroy()
|
|||
return;
|
||||
}
|
||||
|
||||
//if we were in the middle deferred window positioning
|
||||
if (mDeferredPositioner) {
|
||||
VERIFY(::EndDeferWindowPos(mDeferredPositioner));
|
||||
}
|
||||
|
||||
// destroy the nsWindow
|
||||
if (mWnd) {
|
||||
// destroy the nsWindow
|
||||
|
@ -585,7 +611,7 @@ nsIWidget* nsWindow::GetParent(void)
|
|||
if (mWnd) {
|
||||
HWND parent = ::GetParent(mWnd);
|
||||
if (parent) {
|
||||
nsIWidget* widget = (nsIWidget*)::GetWindowLong(mWnd, GWL_USERDATA);
|
||||
widget = (nsIWidget*)((nsWindow *)::GetWindowLong(mWnd, GWL_USERDATA));
|
||||
widget->AddRef();
|
||||
}
|
||||
}
|
||||
|
@ -674,8 +700,23 @@ void nsWindow::Show(PRBool bState)
|
|||
void nsWindow::Move(PRUint32 aX, PRUint32 aY)
|
||||
{
|
||||
if (mWnd) {
|
||||
VERIFY(::SetWindowPos(mWnd, NULL, aX, aY, 0, 0,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE));
|
||||
nsIWidget *par = GetParent();
|
||||
HDWP deferrer = NULL;
|
||||
|
||||
if (nsnull != par) {
|
||||
deferrer = ((nsWindow *)par)->mDeferredPositioner;
|
||||
NS_RELEASE(par);
|
||||
}
|
||||
|
||||
if (NULL != deferrer) {
|
||||
//printf("move: deferring\n");
|
||||
VERIFY(::DeferWindowPos(deferrer, mWnd, NULL, aX, aY, 0, 0,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE));
|
||||
}
|
||||
else {
|
||||
VERIFY(::SetWindowPos(mWnd, NULL, aX, aY, 0, 0,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -687,8 +728,23 @@ void nsWindow::Move(PRUint32 aX, PRUint32 aY)
|
|||
void nsWindow::Resize(PRUint32 aWidth, PRUint32 aHeight)
|
||||
{
|
||||
if (mWnd) {
|
||||
VERIFY(::SetWindowPos(mWnd, NULL, 0, 0, aWidth, aHeight,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE));
|
||||
nsIWidget *par = GetParent();
|
||||
HDWP deferrer = NULL;
|
||||
|
||||
if (nsnull != par) {
|
||||
deferrer = ((nsWindow *)par)->mDeferredPositioner;
|
||||
NS_RELEASE(par);
|
||||
}
|
||||
|
||||
if (NULL != deferrer) {
|
||||
//printf("resize: deferring\n");
|
||||
VERIFY(::DeferWindowPos(deferrer, mWnd, NULL, 0, 0, aWidth, aHeight,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE));
|
||||
}
|
||||
else {
|
||||
VERIFY(::SetWindowPos(mWnd, NULL, 0, 0, aWidth, aHeight,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -701,8 +757,23 @@ void nsWindow::Resize(PRUint32 aWidth, PRUint32 aHeight)
|
|||
void nsWindow::Resize(PRUint32 aX, PRUint32 aY, PRUint32 aWidth, PRUint32 aHeight)
|
||||
{
|
||||
if (mWnd) {
|
||||
VERIFY(::SetWindowPos(mWnd, NULL, aX, aY, aWidth, aHeight,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE));
|
||||
nsIWidget *par = GetParent();
|
||||
HDWP deferrer = NULL;
|
||||
|
||||
if (nsnull != par) {
|
||||
deferrer = ((nsWindow *)par)->mDeferredPositioner;
|
||||
NS_RELEASE(par);
|
||||
}
|
||||
|
||||
if (NULL != deferrer) {
|
||||
//printf("resize: deferring\n");
|
||||
VERIFY(::DeferWindowPos(deferrer, mWnd, NULL, aX, aY, aWidth, aHeight,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE));
|
||||
}
|
||||
else {
|
||||
VERIFY(::SetWindowPos(mWnd, NULL, aX, aY, aWidth, aHeight,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -116,6 +116,8 @@ public:
|
|||
virtual void ScreenToWidget(const nsRect& aOldRect, nsRect& aNewRect);
|
||||
virtual void AddMouseListener(nsIMouseListener * aListener);
|
||||
virtual void AddEventListener(nsIEventListener * aListener);
|
||||
virtual void BeginResizingChildren(void);
|
||||
virtual void EndResizingChildren(void);
|
||||
|
||||
// nsSwitchToUIThread interface
|
||||
virtual BOOL CallMethod(MethodInfo *info);
|
||||
|
@ -219,6 +221,8 @@ protected:
|
|||
};
|
||||
|
||||
static BOOL sIsRegistered;
|
||||
|
||||
HDWP mDeferredPositioner;
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -409,6 +413,14 @@ protected:
|
|||
void ScreenToWidget(const nsRect& aOldRect, nsRect& aNewRect) \
|
||||
{ \
|
||||
nsWindow::ScreenToWidget(aOldRect, aNewRect); \
|
||||
} \
|
||||
void BeginResizingChildren(void) \
|
||||
{ \
|
||||
nsWindow::BeginResizingChildren(); \
|
||||
} \
|
||||
void EndResizingChildren(void) \
|
||||
{ \
|
||||
nsWindow::EndResizingChildren(); \
|
||||
}
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче