Bug 232838. Properly relayout scrollbars if we need to hide one because there's no room. Prefer to hide the horizontal scrollbar if we have to choose between them. r+sr=dbaron,a=choffman

This commit is contained in:
roc+%cs.cmu.edu 2004-03-10 23:52:01 +00:00
Родитель 9b10aac055
Коммит 693c921022
2 изменённых файлов: 218 добавлений и 198 удалений

Просмотреть файл

@ -116,8 +116,8 @@ public:
PRBool AddHorizontalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnBottom); PRBool AddHorizontalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnBottom);
PRBool AddVerticalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight); PRBool AddVerticalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight);
PRBool RemoveHorizontalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnBottom); void RemoveHorizontalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnBottom);
PRBool RemoveVerticalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight); void RemoveVerticalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight);
nsIScrollableView* GetScrollableView(nsIPresContext* aPresContext); nsIScrollableView* GetScrollableView(nsIPresContext* aPresContext);
@ -1117,16 +1117,26 @@ nsGfxScrollFrameInner::AddVerticalScrollbar(nsBoxLayoutState& aState, nsRect& aS
return AddRemoveScrollbar(aState, aScrollAreaSize, aOnRight, PR_FALSE, PR_TRUE); return AddRemoveScrollbar(aState, aScrollAreaSize, aOnRight, PR_FALSE, PR_TRUE);
} }
PRBool void
nsGfxScrollFrameInner::RemoveHorizontalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnTop) nsGfxScrollFrameInner::RemoveHorizontalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnTop)
{ {
return AddRemoveScrollbar(aState, aScrollAreaSize, aOnTop, PR_TRUE, PR_FALSE); // removing a scrollbar should always fit
#ifdef DEBUG
PRBool result =
#endif
AddRemoveScrollbar(aState, aScrollAreaSize, aOnTop, PR_TRUE, PR_FALSE);
NS_ASSERTION(result, "Removing horizontal scrollbar failed to fit??");
} }
PRBool void
nsGfxScrollFrameInner::RemoveVerticalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight) nsGfxScrollFrameInner::RemoveVerticalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight)
{ {
return AddRemoveScrollbar(aState, aScrollAreaSize, aOnRight, PR_FALSE, PR_FALSE); // removing a scrollbar should always fit
#ifdef DEBUG
PRBool result =
#endif
AddRemoveScrollbar(aState, aScrollAreaSize, aOnRight, PR_FALSE, PR_FALSE);
NS_ASSERTION(result, "Removing vertical scrollbar failed to fit??");
} }
PRBool PRBool
@ -1307,28 +1317,34 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
nsRect clientRect(0,0,0,0); nsRect clientRect(0,0,0,0);
mOuter->GetClientRect(clientRect); mOuter->GetClientRect(clientRect);
// get the preferred size of the scrollbars
nsSize hSize(0,0);
nsSize vSize(0,0);
nsSize hMinSize(0,0);
nsSize vMinSize(0,0);
/*
mHScrollbarBox->GetPrefSize(aState, hSize);
mVScrollbarBox->GetPrefSize(aState, vSize);
mHScrollbarBox->GetMinSize(aState, hMinSize);
mVScrollbarBox->GetMinSize(aState, vMinSize);
nsBox::AddMargin(mHScrollbarBox, hSize);
nsBox::AddMargin(mVScrollbarBox, vSize);
nsBox::AddMargin(mHScrollbarBox, hMinSize);
nsBox::AddMargin(mVScrollbarBox, vMinSize);
*/
// the scroll area size starts off as big as our content area // the scroll area size starts off as big as our content area
nsRect scrollAreaRect(clientRect); nsRect scrollAreaRect(clientRect);
/**************
Our basic strategy here is to first try laying out the content with
the scrollbars in their current state. We're hoping that that will
just "work"; the content will overflow wherever there's a scrollbar
already visible. If that does work, then there's no need to lay out
the scrollarea. Otherwise we fix up the scrollbars; first we add a
vertical one to scroll the content if necessary, or remove it if
it's not needed. Then we reflow the content if the scrollbar
changed. Then we add a horizontal scrollbar if necessary (or
remove if not needed), and if that changed, we reflow the content
again. At this point, any scrollbars that are needed to scroll the
content have been added.
In the second phase we check to see if any scrollbars are too small
to display, and if so, we remove them. We check the horizontal
scrollbar first; removing it might make room for the vertical
scrollbar, and if we have room for just one scrollbar we'll save
the vertical one.
Finally we position and size the scrollbars and scrollcorner (the
square that is needed in the corner of the window when two
scrollbars are visible), and reflow any fixed position views
(if we're the viewport and we added or removed a scrollbar).
**************/
nsGfxScrollFrame::ScrollbarStyles styles = mOuter->GetScrollbarStyles(); nsGfxScrollFrame::ScrollbarStyles styles = mOuter->GetScrollbarStyles();
// Look at our style do we always have vertical or horizontal scrollbars? // Look at our style do we always have vertical or horizontal scrollbars?
@ -1364,18 +1380,16 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
if (mHasVerticalScrollbar) { if (mHasVerticalScrollbar) {
// We left room for the vertical scrollbar, but it's not needed; // We left room for the vertical scrollbar, but it's not needed;
// remove it. // remove it.
if (RemoveVerticalScrollbar(aState, scrollAreaRect, scrollBarRight)) { RemoveVerticalScrollbar(aState, scrollAreaRect, scrollBarRight);
needsLayout = PR_TRUE; needsLayout = PR_TRUE;
SetAttribute(mVScrollbarBox, nsXULAtoms::curpos, 0); SetAttribute(mVScrollbarBox, nsXULAtoms::curpos, 0);
} }
}
} else { } else {
if (!mHasVerticalScrollbar) { if (!mHasVerticalScrollbar) {
// We didn't leave room for the vertical scrollbar, but it turns // We didn't leave room for the vertical scrollbar, but it turns
// out we needed it // out we needed it
if (AddVerticalScrollbar(aState, scrollAreaRect, scrollBarRight)) if (AddVerticalScrollbar(aState, scrollAreaRect, scrollBarRight))
needsLayout = PR_TRUE; needsLayout = PR_TRUE;
} }
} }
@ -1433,7 +1447,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
// if the area is smaller or equal to and we have a scrollbar then // if the area is smaller or equal to and we have a scrollbar then
// remove it. // remove it.
if (mHasHorizontalScrollbar) { if (mHasHorizontalScrollbar) {
if (RemoveHorizontalScrollbar(aState, scrollAreaRect, scrollBarBottom)) RemoveHorizontalScrollbar(aState, scrollAreaRect, scrollBarBottom);
needsLayout = PR_TRUE; needsLayout = PR_TRUE;
SetAttribute(mHScrollbarBox, nsXULAtoms::curpos, 0); SetAttribute(mHScrollbarBox, nsXULAtoms::curpos, 0);
} }
@ -1469,89 +1483,85 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
if (fm) if (fm)
fm->GetHeight(fontHeight); fm->GetHeight(fontHeight);
// get the preferred size of the scrollbars
nsSize hSize(0,0);
nsSize vSize(0,0);
nsSize hMinSize(0,0);
nsSize vMinSize(0,0);
if (mHScrollbarBox && mHasHorizontalScrollbar) {
mHScrollbarBox->GetPrefSize(aState, hSize);
mHScrollbarBox->GetMinSize(aState, hMinSize);
nsBox::AddMargin(mHScrollbarBox, hSize);
nsBox::AddMargin(mHScrollbarBox, hMinSize);
}
if (mVScrollbarBox && mHasVerticalScrollbar) {
mVScrollbarBox->GetPrefSize(aState, vSize);
mVScrollbarBox->GetMinSize(aState, vMinSize);
nsBox::AddMargin(mVScrollbarBox, vSize);
nsBox::AddMargin(mVScrollbarBox, vMinSize);
}
NS_ASSERTION(vMinSize.width == vSize.width, "vertical scrollbar can change width");
NS_ASSERTION(hMinSize.height == hSize.height, "horizontal scrollbar can change height");
// Disable scrollbars that are too small
// Disable horizontal scrollbar first. If we have to disable only one
// scrollbar, we'd rather keep the vertical scrollbar.
if (mHasHorizontalScrollbar &&
(hMinSize.width > clientRect.width - vSize.width
|| hMinSize.height > clientRect.height)) {
RemoveHorizontalScrollbar(aState, scrollAreaRect, scrollBarBottom);
needsLayout = PR_TRUE;
SetAttribute(mHScrollbarBox, nsXULAtoms::curpos, 0);
// set the scrollbar to zero height to make it go away
hSize.height = 0;
hMinSize.height = 0;
}
// Now disable vertical scrollbar if necessary
if (mHasVerticalScrollbar &&
(vMinSize.height > clientRect.height - hSize.height
|| vMinSize.width > clientRect.width)) {
RemoveVerticalScrollbar(aState, scrollAreaRect, scrollBarRight);
needsLayout = PR_TRUE;
SetAttribute(mVScrollbarBox, nsXULAtoms::curpos, 0);
// set the scrollbar to zero width to make it go away
vSize.width = 0;
vMinSize.width = 0;
}
nscoord maxX = scrolledContentSize.width - scrollAreaRect.width; nscoord maxX = scrolledContentSize.width - scrollAreaRect.width;
nscoord maxY = scrolledContentSize.height - scrollAreaRect.height; nscoord maxY = scrolledContentSize.height - scrollAreaRect.height;
nsIScrollableView* scrollable = GetScrollableView(presContext); nsIScrollableView* scrollable = GetScrollableView(presContext);
scrollable->SetLineHeight(fontHeight); scrollable->SetLineHeight(fontHeight);
if (mHScrollbarBox) if (mVScrollbarBox) {
mHScrollbarBox->GetPrefSize(aState, hSize);
if (mVScrollbarBox)
mVScrollbarBox->GetPrefSize(aState, vSize);
// layout vertical scrollbar
nsRect vRect(clientRect);
vRect.width = mHasVerticalScrollbar ? vSize.width : 0;
vRect.y = clientRect.y;
if (mHasHorizontalScrollbar) {
vRect.height -= hSize.height;
if (!scrollBarBottom)
vRect.y += hSize.height;
}
vRect.x = clientRect.x;
if (scrollBarRight)
vRect.x += clientRect.width - vRect.width;
if (mHasVerticalScrollbar && mVScrollbarBox) {
SetAttribute(mVScrollbarBox, nsXULAtoms::maxpos, maxY); SetAttribute(mVScrollbarBox, nsXULAtoms::maxpos, maxY);
SetAttribute(mVScrollbarBox, nsXULAtoms::pageincrement, nscoord(scrollAreaRect.height - fontHeight)); SetAttribute(mVScrollbarBox, nsXULAtoms::pageincrement, nscoord(scrollAreaRect.height - fontHeight));
SetAttribute(mVScrollbarBox, nsXULAtoms::increment, fontHeight); SetAttribute(mVScrollbarBox, nsXULAtoms::increment, fontHeight);
}
if (mVScrollbarBox) { nsRect vRect(scrollAreaRect);
vRect.width = vSize.width;
vRect.x = scrollBarRight ? scrollAreaRect.XMost() : clientRect.x;
nsMargin margin;
mVScrollbarBox->GetMargin(margin);
vRect.Deflate(margin);
LayoutBox(aState, mVScrollbarBox, vRect); LayoutBox(aState, mVScrollbarBox, vRect);
mVScrollbarBox->GetPrefSize(aState, vSize);
mVScrollbarBox->GetMinSize(aState, vMinSize);
}
if (mHasVerticalScrollbar && mVScrollbarBox && (vMinSize.width > vRect.width || vMinSize.height > vRect.height)) {
if (RemoveVerticalScrollbar(aState, scrollAreaRect, scrollBarRight)) {
needsLayout = PR_TRUE;
SetAttribute(mVScrollbarBox, nsXULAtoms::curpos, 0);
}
mVScrollbarBox->GetPrefSize(aState, vSize);
}
// layout horizontal scrollbar
nsRect hRect(clientRect);
hRect.height = mHasHorizontalScrollbar ? hSize.height : 0;
hRect.x = clientRect.x;
if (mHasVerticalScrollbar) {
hRect.width -= vSize.width;
if (!scrollBarRight)
hRect.x += vSize.width;
}
hRect.y = clientRect.y;
if (scrollBarBottom)
hRect.y += clientRect.height - hRect.height;
if (mHasHorizontalScrollbar && mHScrollbarBox) {
SetAttribute(mHScrollbarBox, nsXULAtoms::maxpos, maxX);
SetAttribute(mHScrollbarBox, nsXULAtoms::pageincrement, nscoord(float(scrollAreaRect.width)*0.8));
SetAttribute(mHScrollbarBox, nsXULAtoms::increment, 10*mOnePixel);
} }
if (mHScrollbarBox) { if (mHScrollbarBox) {
LayoutBox(aState, mHScrollbarBox, hRect); SetAttribute(mHScrollbarBox, nsXULAtoms::maxpos, maxX);
mHScrollbarBox->GetMinSize(aState, hMinSize); SetAttribute(mHScrollbarBox, nsXULAtoms::pageincrement, nscoord(float(scrollAreaRect.width)*0.8));
} SetAttribute(mHScrollbarBox, nsXULAtoms::increment, 10*mOnePixel);
if (mHasHorizontalScrollbar && mHScrollbarBox && (hMinSize.width > hRect.width || hMinSize.height > hRect.height)) { nsRect hRect(scrollAreaRect);
if (RemoveHorizontalScrollbar(aState, scrollAreaRect, scrollBarBottom)) { hRect.height = hSize.height;
needsLayout = PR_TRUE; hRect.y = scrollBarBottom ? scrollAreaRect.YMost() : clientRect.y;
SetAttribute(mHScrollbarBox, nsXULAtoms::curpos, 0); nsMargin margin;
} mHScrollbarBox->GetMargin(margin);
hRect.Deflate(margin);
LayoutBox(aState, mHScrollbarBox, hRect);
} }
// we only need to set the rect. The inner child stays the same size. // we only need to set the rect. The inner child stays the same size.

Просмотреть файл

@ -116,8 +116,8 @@ public:
PRBool AddHorizontalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnBottom); PRBool AddHorizontalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnBottom);
PRBool AddVerticalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight); PRBool AddVerticalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight);
PRBool RemoveHorizontalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnBottom); void RemoveHorizontalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnBottom);
PRBool RemoveVerticalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight); void RemoveVerticalScrollbar (nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight);
nsIScrollableView* GetScrollableView(nsIPresContext* aPresContext); nsIScrollableView* GetScrollableView(nsIPresContext* aPresContext);
@ -1117,16 +1117,26 @@ nsGfxScrollFrameInner::AddVerticalScrollbar(nsBoxLayoutState& aState, nsRect& aS
return AddRemoveScrollbar(aState, aScrollAreaSize, aOnRight, PR_FALSE, PR_TRUE); return AddRemoveScrollbar(aState, aScrollAreaSize, aOnRight, PR_FALSE, PR_TRUE);
} }
PRBool void
nsGfxScrollFrameInner::RemoveHorizontalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnTop) nsGfxScrollFrameInner::RemoveHorizontalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnTop)
{ {
return AddRemoveScrollbar(aState, aScrollAreaSize, aOnTop, PR_TRUE, PR_FALSE); // removing a scrollbar should always fit
#ifdef DEBUG
PRBool result =
#endif
AddRemoveScrollbar(aState, aScrollAreaSize, aOnTop, PR_TRUE, PR_FALSE);
NS_ASSERTION(result, "Removing horizontal scrollbar failed to fit??");
} }
PRBool void
nsGfxScrollFrameInner::RemoveVerticalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight) nsGfxScrollFrameInner::RemoveVerticalScrollbar(nsBoxLayoutState& aState, nsRect& aScrollAreaSize, PRBool aOnRight)
{ {
return AddRemoveScrollbar(aState, aScrollAreaSize, aOnRight, PR_FALSE, PR_FALSE); // removing a scrollbar should always fit
#ifdef DEBUG
PRBool result =
#endif
AddRemoveScrollbar(aState, aScrollAreaSize, aOnRight, PR_FALSE, PR_FALSE);
NS_ASSERTION(result, "Removing vertical scrollbar failed to fit??");
} }
PRBool PRBool
@ -1307,28 +1317,34 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
nsRect clientRect(0,0,0,0); nsRect clientRect(0,0,0,0);
mOuter->GetClientRect(clientRect); mOuter->GetClientRect(clientRect);
// get the preferred size of the scrollbars
nsSize hSize(0,0);
nsSize vSize(0,0);
nsSize hMinSize(0,0);
nsSize vMinSize(0,0);
/*
mHScrollbarBox->GetPrefSize(aState, hSize);
mVScrollbarBox->GetPrefSize(aState, vSize);
mHScrollbarBox->GetMinSize(aState, hMinSize);
mVScrollbarBox->GetMinSize(aState, vMinSize);
nsBox::AddMargin(mHScrollbarBox, hSize);
nsBox::AddMargin(mVScrollbarBox, vSize);
nsBox::AddMargin(mHScrollbarBox, hMinSize);
nsBox::AddMargin(mVScrollbarBox, vMinSize);
*/
// the scroll area size starts off as big as our content area // the scroll area size starts off as big as our content area
nsRect scrollAreaRect(clientRect); nsRect scrollAreaRect(clientRect);
/**************
Our basic strategy here is to first try laying out the content with
the scrollbars in their current state. We're hoping that that will
just "work"; the content will overflow wherever there's a scrollbar
already visible. If that does work, then there's no need to lay out
the scrollarea. Otherwise we fix up the scrollbars; first we add a
vertical one to scroll the content if necessary, or remove it if
it's not needed. Then we reflow the content if the scrollbar
changed. Then we add a horizontal scrollbar if necessary (or
remove if not needed), and if that changed, we reflow the content
again. At this point, any scrollbars that are needed to scroll the
content have been added.
In the second phase we check to see if any scrollbars are too small
to display, and if so, we remove them. We check the horizontal
scrollbar first; removing it might make room for the vertical
scrollbar, and if we have room for just one scrollbar we'll save
the vertical one.
Finally we position and size the scrollbars and scrollcorner (the
square that is needed in the corner of the window when two
scrollbars are visible), and reflow any fixed position views
(if we're the viewport and we added or removed a scrollbar).
**************/
nsGfxScrollFrame::ScrollbarStyles styles = mOuter->GetScrollbarStyles(); nsGfxScrollFrame::ScrollbarStyles styles = mOuter->GetScrollbarStyles();
// Look at our style do we always have vertical or horizontal scrollbars? // Look at our style do we always have vertical or horizontal scrollbars?
@ -1364,18 +1380,16 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
if (mHasVerticalScrollbar) { if (mHasVerticalScrollbar) {
// We left room for the vertical scrollbar, but it's not needed; // We left room for the vertical scrollbar, but it's not needed;
// remove it. // remove it.
if (RemoveVerticalScrollbar(aState, scrollAreaRect, scrollBarRight)) { RemoveVerticalScrollbar(aState, scrollAreaRect, scrollBarRight);
needsLayout = PR_TRUE; needsLayout = PR_TRUE;
SetAttribute(mVScrollbarBox, nsXULAtoms::curpos, 0); SetAttribute(mVScrollbarBox, nsXULAtoms::curpos, 0);
} }
}
} else { } else {
if (!mHasVerticalScrollbar) { if (!mHasVerticalScrollbar) {
// We didn't leave room for the vertical scrollbar, but it turns // We didn't leave room for the vertical scrollbar, but it turns
// out we needed it // out we needed it
if (AddVerticalScrollbar(aState, scrollAreaRect, scrollBarRight)) if (AddVerticalScrollbar(aState, scrollAreaRect, scrollBarRight))
needsLayout = PR_TRUE; needsLayout = PR_TRUE;
} }
} }
@ -1433,7 +1447,7 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
// if the area is smaller or equal to and we have a scrollbar then // if the area is smaller or equal to and we have a scrollbar then
// remove it. // remove it.
if (mHasHorizontalScrollbar) { if (mHasHorizontalScrollbar) {
if (RemoveHorizontalScrollbar(aState, scrollAreaRect, scrollBarBottom)) RemoveHorizontalScrollbar(aState, scrollAreaRect, scrollBarBottom);
needsLayout = PR_TRUE; needsLayout = PR_TRUE;
SetAttribute(mHScrollbarBox, nsXULAtoms::curpos, 0); SetAttribute(mHScrollbarBox, nsXULAtoms::curpos, 0);
} }
@ -1469,89 +1483,85 @@ nsGfxScrollFrameInner::Layout(nsBoxLayoutState& aState)
if (fm) if (fm)
fm->GetHeight(fontHeight); fm->GetHeight(fontHeight);
// get the preferred size of the scrollbars
nsSize hSize(0,0);
nsSize vSize(0,0);
nsSize hMinSize(0,0);
nsSize vMinSize(0,0);
if (mHScrollbarBox && mHasHorizontalScrollbar) {
mHScrollbarBox->GetPrefSize(aState, hSize);
mHScrollbarBox->GetMinSize(aState, hMinSize);
nsBox::AddMargin(mHScrollbarBox, hSize);
nsBox::AddMargin(mHScrollbarBox, hMinSize);
}
if (mVScrollbarBox && mHasVerticalScrollbar) {
mVScrollbarBox->GetPrefSize(aState, vSize);
mVScrollbarBox->GetMinSize(aState, vMinSize);
nsBox::AddMargin(mVScrollbarBox, vSize);
nsBox::AddMargin(mVScrollbarBox, vMinSize);
}
NS_ASSERTION(vMinSize.width == vSize.width, "vertical scrollbar can change width");
NS_ASSERTION(hMinSize.height == hSize.height, "horizontal scrollbar can change height");
// Disable scrollbars that are too small
// Disable horizontal scrollbar first. If we have to disable only one
// scrollbar, we'd rather keep the vertical scrollbar.
if (mHasHorizontalScrollbar &&
(hMinSize.width > clientRect.width - vSize.width
|| hMinSize.height > clientRect.height)) {
RemoveHorizontalScrollbar(aState, scrollAreaRect, scrollBarBottom);
needsLayout = PR_TRUE;
SetAttribute(mHScrollbarBox, nsXULAtoms::curpos, 0);
// set the scrollbar to zero height to make it go away
hSize.height = 0;
hMinSize.height = 0;
}
// Now disable vertical scrollbar if necessary
if (mHasVerticalScrollbar &&
(vMinSize.height > clientRect.height - hSize.height
|| vMinSize.width > clientRect.width)) {
RemoveVerticalScrollbar(aState, scrollAreaRect, scrollBarRight);
needsLayout = PR_TRUE;
SetAttribute(mVScrollbarBox, nsXULAtoms::curpos, 0);
// set the scrollbar to zero width to make it go away
vSize.width = 0;
vMinSize.width = 0;
}
nscoord maxX = scrolledContentSize.width - scrollAreaRect.width; nscoord maxX = scrolledContentSize.width - scrollAreaRect.width;
nscoord maxY = scrolledContentSize.height - scrollAreaRect.height; nscoord maxY = scrolledContentSize.height - scrollAreaRect.height;
nsIScrollableView* scrollable = GetScrollableView(presContext); nsIScrollableView* scrollable = GetScrollableView(presContext);
scrollable->SetLineHeight(fontHeight); scrollable->SetLineHeight(fontHeight);
if (mHScrollbarBox) if (mVScrollbarBox) {
mHScrollbarBox->GetPrefSize(aState, hSize);
if (mVScrollbarBox)
mVScrollbarBox->GetPrefSize(aState, vSize);
// layout vertical scrollbar
nsRect vRect(clientRect);
vRect.width = mHasVerticalScrollbar ? vSize.width : 0;
vRect.y = clientRect.y;
if (mHasHorizontalScrollbar) {
vRect.height -= hSize.height;
if (!scrollBarBottom)
vRect.y += hSize.height;
}
vRect.x = clientRect.x;
if (scrollBarRight)
vRect.x += clientRect.width - vRect.width;
if (mHasVerticalScrollbar && mVScrollbarBox) {
SetAttribute(mVScrollbarBox, nsXULAtoms::maxpos, maxY); SetAttribute(mVScrollbarBox, nsXULAtoms::maxpos, maxY);
SetAttribute(mVScrollbarBox, nsXULAtoms::pageincrement, nscoord(scrollAreaRect.height - fontHeight)); SetAttribute(mVScrollbarBox, nsXULAtoms::pageincrement, nscoord(scrollAreaRect.height - fontHeight));
SetAttribute(mVScrollbarBox, nsXULAtoms::increment, fontHeight); SetAttribute(mVScrollbarBox, nsXULAtoms::increment, fontHeight);
}
if (mVScrollbarBox) { nsRect vRect(scrollAreaRect);
vRect.width = vSize.width;
vRect.x = scrollBarRight ? scrollAreaRect.XMost() : clientRect.x;
nsMargin margin;
mVScrollbarBox->GetMargin(margin);
vRect.Deflate(margin);
LayoutBox(aState, mVScrollbarBox, vRect); LayoutBox(aState, mVScrollbarBox, vRect);
mVScrollbarBox->GetPrefSize(aState, vSize);
mVScrollbarBox->GetMinSize(aState, vMinSize);
}
if (mHasVerticalScrollbar && mVScrollbarBox && (vMinSize.width > vRect.width || vMinSize.height > vRect.height)) {
if (RemoveVerticalScrollbar(aState, scrollAreaRect, scrollBarRight)) {
needsLayout = PR_TRUE;
SetAttribute(mVScrollbarBox, nsXULAtoms::curpos, 0);
}
mVScrollbarBox->GetPrefSize(aState, vSize);
}
// layout horizontal scrollbar
nsRect hRect(clientRect);
hRect.height = mHasHorizontalScrollbar ? hSize.height : 0;
hRect.x = clientRect.x;
if (mHasVerticalScrollbar) {
hRect.width -= vSize.width;
if (!scrollBarRight)
hRect.x += vSize.width;
}
hRect.y = clientRect.y;
if (scrollBarBottom)
hRect.y += clientRect.height - hRect.height;
if (mHasHorizontalScrollbar && mHScrollbarBox) {
SetAttribute(mHScrollbarBox, nsXULAtoms::maxpos, maxX);
SetAttribute(mHScrollbarBox, nsXULAtoms::pageincrement, nscoord(float(scrollAreaRect.width)*0.8));
SetAttribute(mHScrollbarBox, nsXULAtoms::increment, 10*mOnePixel);
} }
if (mHScrollbarBox) { if (mHScrollbarBox) {
LayoutBox(aState, mHScrollbarBox, hRect); SetAttribute(mHScrollbarBox, nsXULAtoms::maxpos, maxX);
mHScrollbarBox->GetMinSize(aState, hMinSize); SetAttribute(mHScrollbarBox, nsXULAtoms::pageincrement, nscoord(float(scrollAreaRect.width)*0.8));
} SetAttribute(mHScrollbarBox, nsXULAtoms::increment, 10*mOnePixel);
if (mHasHorizontalScrollbar && mHScrollbarBox && (hMinSize.width > hRect.width || hMinSize.height > hRect.height)) { nsRect hRect(scrollAreaRect);
if (RemoveHorizontalScrollbar(aState, scrollAreaRect, scrollBarBottom)) { hRect.height = hSize.height;
needsLayout = PR_TRUE; hRect.y = scrollBarBottom ? scrollAreaRect.YMost() : clientRect.y;
SetAttribute(mHScrollbarBox, nsXULAtoms::curpos, 0); nsMargin margin;
} mHScrollbarBox->GetMargin(margin);
hRect.Deflate(margin);
LayoutBox(aState, mHScrollbarBox, hRect);
} }
// we only need to set the rect. The inner child stays the same size. // we only need to set the rect. The inner child stays the same size.