зеркало из https://github.com/mozilla/gecko-dev.git
Added unconstrainted reflow optimizations
reworked reflow to more accurately calculate its size r=kmcclusk,dcone bug=12653
This commit is contained in:
Родитель
398cac9ed2
Коммит
05e6af0c80
|
@ -670,39 +670,12 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
#endif
|
||||
|
||||
|
||||
// XXX Temporary Fix for too many resize reflows
|
||||
#ifdef OPTIMIZE_RESIZE_RELOW
|
||||
if (aReflowState.reason == eReflowReason_Resize) {
|
||||
if (NS_UNCONSTRAINEDSIZE == aReflowState.mComputedWidth &&
|
||||
NS_UNCONSTRAINEDSIZE == aReflowState.mComputedHeight) {
|
||||
|
||||
if (mCacheSize.width > -1 && mCacheSize.height > -1) {
|
||||
aDesiredSize.width = mCacheSize.width;
|
||||
aDesiredSize.height = mCacheSize.height;
|
||||
if (aDesiredSize.maxElementSize != nsnull) {
|
||||
aDesiredSize.maxElementSize->width = mCachedMaxElementSize.width;
|
||||
aDesiredSize.maxElementSize->height = mCachedMaxElementSize.height;
|
||||
}
|
||||
aDesiredSize.ascent = aDesiredSize.height;
|
||||
aDesiredSize.descent = 0;
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;
|
||||
}
|
||||
} else {
|
||||
if (mCacheSize.width == aReflowState.mComputedWidth &&
|
||||
mCacheSize.height == aReflowState.mComputedHeight) {
|
||||
if (aDesiredSize.maxElementSize != nsnull) {
|
||||
aDesiredSize.maxElementSize->width = mCachedMaxElementSize.width;
|
||||
aDesiredSize.maxElementSize->height = mCachedMaxElementSize.height;
|
||||
}
|
||||
aDesiredSize.ascent = aDesiredSize.height;
|
||||
aDesiredSize.descent = 0;
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
nsresult skiprv = nsFormControlFrame::SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext,
|
||||
aDesiredSize, aReflowState, aStatus);
|
||||
if (NS_SUCCEEDED(skiprv)) {
|
||||
return skiprv;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsIFrame* buttonFrame = GetButtonFrame(aPresContext);
|
||||
|
@ -759,11 +732,6 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
displayFrame->GetRect(displayRect);
|
||||
buttonFrame->GetRect(buttonRect);
|
||||
if ((oldDisplayRect == displayRect) && (oldButtonRect == buttonRect)) {
|
||||
// Reposition the popup.
|
||||
//nsRect absoluteTwips;
|
||||
//nsRect absolutePixels;
|
||||
//GetAbsoluteFramePosition(aPresContext, displayFrame, absoluteTwips, absolutePixels);
|
||||
//PositionDropdown(aPresContext, displayRect.height, absoluteTwips, absolutePixels);
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return rv;
|
||||
}
|
||||
|
@ -774,6 +742,18 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
firstPassState.reflowCommand = nsnull;
|
||||
}
|
||||
|
||||
// the default size of the of scrollbar
|
||||
// that will be the default width of the dropdown button
|
||||
// the height will be the height of the text
|
||||
nscoord scrollbarWidth = -1;
|
||||
nsCOMPtr<nsIDeviceContext> dx;
|
||||
aPresContext->GetDeviceContext(getter_AddRefs(dx));
|
||||
if (dx) {
|
||||
float sbWidth;
|
||||
float sbHeight;
|
||||
dx->GetScrollBarDimensions(sbWidth, sbHeight);
|
||||
scrollbarWidth = (nscoord)sbWidth;
|
||||
}
|
||||
|
||||
//Set the desired size for the button and display frame
|
||||
if (NS_UNCONSTRAINEDSIZE == firstPassState.mComputedWidth) {
|
||||
|
@ -796,28 +776,35 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
mListControlFrame->GetNumberOfOptions(&length);
|
||||
dropdownFrame->GetRect(dropdownRect);
|
||||
|
||||
const nsStyleSpacing* dropSpacing;
|
||||
dropdownFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)dropSpacing);
|
||||
nsMargin dropBorderPadding;
|
||||
dropBorderPadding.SizeTo(0, 0, 0, 0);
|
||||
dropSpacing->CalcBorderPaddingFor(dropdownFrame, dropBorderPadding);
|
||||
dropdownRect.width -= (dropBorderPadding.left + dropBorderPadding.right);
|
||||
|
||||
// Get maximum size and height of a option in the dropdown
|
||||
mListControlFrame->GetMaximumSize(size);
|
||||
|
||||
// Set width of display to match width of the drop down
|
||||
SetChildFrameSize(displayFrame, dropdownRect.width, size.height);
|
||||
if (scrollbarWidth > 0) {
|
||||
size.width = scrollbarWidth;
|
||||
}
|
||||
const nsStyleSpacing* dspSpacing;
|
||||
displayFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)dspSpacing);
|
||||
nsMargin dspBorderPadding;
|
||||
dspBorderPadding.SizeTo(0, 0, 0, 0);
|
||||
dspSpacing->CalcBorderPaddingFor(displayFrame, dspBorderPadding);
|
||||
|
||||
// Set width of display to match width of the drop down
|
||||
SetChildFrameSize(displayFrame, dropdownRect.width-size.width+dspBorderPadding.left+dspBorderPadding.right,
|
||||
size.height+dspBorderPadding.top+dspBorderPadding.bottom);
|
||||
|
||||
// the default size of the of scrollbar
|
||||
// that will be the default width of the dropdown button
|
||||
// the height will be the height of the text
|
||||
nsCOMPtr<nsIDeviceContext> dx;
|
||||
aPresContext->GetDeviceContext(getter_AddRefs(dx));
|
||||
if (dx) {
|
||||
float sbWidth;
|
||||
float sbHeight;
|
||||
dx->GetScrollBarDimensions(sbWidth, sbHeight);
|
||||
size.width = (nscoord)sbWidth;
|
||||
}
|
||||
// Size the button
|
||||
SetChildFrameSize(buttonFrame, size.width, size.height);
|
||||
|
||||
// Reflow display + button
|
||||
nsAreaFrame::Reflow(aPresContext, aDesiredSize, firstPassState, aStatus);
|
||||
|
||||
displayFrame->GetRect(displayRect);
|
||||
buttonFrame->GetRect(buttonRect);
|
||||
buttonRect.y = displayRect.y;
|
||||
|
@ -831,6 +818,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
if (maxElementSize) {
|
||||
delete maxElementSize;
|
||||
}
|
||||
|
||||
} else {
|
||||
// A width has been specified for the select.
|
||||
// Make the display frame's width + button frame width = the width specified.
|
||||
|
@ -840,30 +828,37 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
nsSize size;
|
||||
mListControlFrame->GetMaximumSize(size);
|
||||
|
||||
// Size the button to be the same height as the displayFrame
|
||||
SetChildFrameSize(buttonFrame, size.height, size.height);
|
||||
if (scrollbarWidth > 0) {
|
||||
size.width = scrollbarWidth;
|
||||
}
|
||||
// Size the button to be the same as the scrollbar width
|
||||
SetChildFrameSize(buttonFrame, size.width, size.height);
|
||||
|
||||
// Compute display width
|
||||
// Since the button's width is the same as its height
|
||||
// we subtract size.height (the width)
|
||||
nscoord displayWidth = firstPassState.mComputedWidth - size.height;
|
||||
nscoord displayWidth = firstPassState.mComputedWidth - size.width;
|
||||
// nsAreaFrame::Reflow adds in the border and padding so we need to remove it
|
||||
displayWidth -= borderPadding.left + borderPadding.right;
|
||||
//displayWidth -= borderPadding.left + borderPadding.right;
|
||||
|
||||
// Set the displayFrame to match the displayWidth computed above
|
||||
// Set the displayFrame to match the displayWidth computed above
|
||||
SetChildFrameSize(displayFrame, displayWidth, size.height);
|
||||
|
||||
// Reflow again with the width of the display frame set.
|
||||
// Reflow again with the width of the display frame set.
|
||||
nsAreaFrame::Reflow(aPresContext, aDesiredSize, firstPassState, aStatus);
|
||||
// nsAreaFrame::Reflow adds in the border and padding so we need to remove it
|
||||
// XXX rods - this hould not be subtracted in
|
||||
//aDesiredSize.width -= borderPadding.left + borderPadding.right;
|
||||
//aDesiredSize.width += borderPadding.left + borderPadding.right;
|
||||
|
||||
// Reflow the dropdown list to match the width of the display + button
|
||||
ReflowComboChildFrame(dropdownFrame, aPresContext, dropdownDesiredSize, firstPassState, aStatus, aDesiredSize.width, NS_UNCONSTRAINEDSIZE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Set the max element size to be the same as the desired element size.
|
||||
if (nsnull != aDesiredSize.maxElementSize) {
|
||||
aDesiredSize.maxElementSize->width = aDesiredSize.width;
|
||||
aDesiredSize.maxElementSize->height = aDesiredSize.height;
|
||||
}
|
||||
|
||||
nsRect absoluteTwips;
|
||||
nsRect absolutePixels;
|
||||
GetAbsoluteFramePosition(aPresContext, this, absoluteTwips, absolutePixels);
|
||||
|
@ -871,19 +866,10 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
#if 0
|
||||
COMPARE_QUIRK_SIZE("nsComboboxControlFrame", 56, 22)
|
||||
#endif
|
||||
|
||||
// XXX Temporary Fix for too many resize reflows
|
||||
#ifdef OPTIMIZE_RESIZE_RELOW
|
||||
mCacheSize.width = aDesiredSize.width;
|
||||
mCacheSize.height = aDesiredSize.height;
|
||||
if (aDesiredSize.maxElementSize != nsnull) {
|
||||
mCachedMaxElementSize.width = aDesiredSize.maxElementSize->width;
|
||||
mCachedMaxElementSize.height = aDesiredSize.maxElementSize->height;
|
||||
}
|
||||
COMPARE_QUIRK_SIZE("nsComboboxControlFrame", 127, 22)
|
||||
#endif
|
||||
|
||||
nsFormControlFrame::SetupCachedSizes(mCacheSize, mCachedMaxElementSize, aDesiredSize);
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
#ifndef nsComboboxControlFrame_h___
|
||||
#define nsComboboxControlFrame_h___
|
||||
|
||||
#define OPTIMIZE_RESIZE_RELOW
|
||||
|
||||
#include "nsAreaFrame.h"
|
||||
#include "nsIFormControlFrame.h"
|
||||
#include "nsIComboboxControlFrame.h"
|
||||
|
@ -211,11 +209,9 @@ protected:
|
|||
nsIListControlFrame * mListControlFrame; // ListControl Interface for the dropdown frame
|
||||
PRBool mIgnoreFocus; // Tells the combo to ignore all focus notifications
|
||||
|
||||
// XXX Temporary Fix for too many resize reflows
|
||||
#ifdef OPTIMIZE_RESIZE_RELOW
|
||||
//Resize Reflow OpitmizationSize;
|
||||
nsSize mCacheSize;
|
||||
nsSize mCachedMaxElementSize;
|
||||
#endif
|
||||
|
||||
private:
|
||||
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
|
||||
|
|
|
@ -112,6 +112,11 @@ nsListControlFrame::nsListControlFrame()
|
|||
mIsAllContentHere = PR_FALSE;
|
||||
mIsAllFramesHere = PR_FALSE;
|
||||
mHasBeenInitialized = PR_FALSE;
|
||||
|
||||
mCacheSize.width = -1;
|
||||
mCacheSize.height = -1;
|
||||
mCachedMaxElementSize.width = -1;
|
||||
mCachedMaxElementSize.height = -1;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -270,6 +275,13 @@ nsresult nsListControlFrame::CountAllChild(nsIDOMNode * aNode, PRInt32& aCount)
|
|||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
PRInt32 GetVal(PRInt32 aVal)
|
||||
{
|
||||
return aVal == NS_UNCONSTRAINEDSIZE?-1:aVal;
|
||||
}
|
||||
static int cnt = 0;
|
||||
*/
|
||||
//---------------------------------------------------------
|
||||
// Reflow is overriden to constrain the listbox height to the number of rows and columns
|
||||
// specified.
|
||||
|
@ -290,6 +302,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
#endif // DEBUG_rodsXXX
|
||||
|
||||
|
||||
#if 0
|
||||
// reflow optimization - why reflow if all the contents
|
||||
// and frames aren't there yet
|
||||
|
@ -331,7 +344,24 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
shell->ExitReflowLock(PR_TRUE, PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 1
|
||||
nsresult skiprv = nsFormControlFrame::SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext,
|
||||
aDesiredSize, aReflowState, aStatus);
|
||||
if (NS_SUCCEEDED(skiprv)) {
|
||||
/*printf("%3d Skipping: %4d,%4d %4d,%4d %4d,%4d %4d,%4d\n", cnt++, GetVal(aReflowState.mComputedWidth), GetVal(aReflowState.mComputedHeight),
|
||||
GetVal(aReflowState.availableWidth), GetVal(aReflowState.availableHeight),
|
||||
GetVal(aReflowState.mComputedMaxWidth), GetVal(aReflowState.mComputedMaxHeight),
|
||||
aDesiredSize.width, aDesiredSize.height);
|
||||
*/
|
||||
return skiprv;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
printf("%3d Not Skip: %4d,%4d %4d,%4d %4d,%4d", cnt++, GetVal(aReflowState.mComputedWidth), GetVal(aReflowState.mComputedHeight),
|
||||
GetVal(aReflowState.availableWidth), GetVal(aReflowState.availableHeight),
|
||||
GetVal(aReflowState.mComputedMaxWidth), GetVal(aReflowState.mComputedMaxHeight));
|
||||
*/
|
||||
// Strategy: Let the inherited reflow happen as though the width and height of the
|
||||
// ScrollFrame are big enough to allow the listbox to
|
||||
// shrink to fit the longest option element line in the list.
|
||||
|
@ -395,7 +425,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
// to the maxElementSize, so these need to be subtracted
|
||||
nscoord scrolledAreaWidth = scrolledAreaDesiredSize.maxElementSize->width;
|
||||
nscoord scrolledAreaHeight = scrolledAreaDesiredSize.height;
|
||||
|
||||
//printf("(%d) ", scrolledAreaWidth);
|
||||
// Keep the oringal values
|
||||
mMaxWidth = scrolledAreaWidth;
|
||||
mMaxHeight = scrolledAreaDesiredSize.maxElementSize->height;
|
||||
|
@ -413,10 +443,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
nscoord scrollbarWidth = NSToCoordRound(sbWidth);
|
||||
//nscoord scrollbarHeight = NSToCoordRound(sbHeight);
|
||||
|
||||
// Subtract out the scrollbar width
|
||||
scrolledAreaWidth -= scrollbarWidth;
|
||||
|
||||
// Subtract out the borders
|
||||
// Subtract out the borders
|
||||
nsMargin border;
|
||||
if (!aReflowState.mStyleSpacing->GetBorder(border)) {
|
||||
NS_NOTYETIMPLEMENTED("percentage border");
|
||||
|
@ -429,24 +456,25 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
padding.SizeTo(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
scrolledAreaWidth -= (border.left + border.right + padding.left + padding.right);
|
||||
scrolledAreaHeight -= (border.top + border.bottom);
|
||||
mMaxWidth -= (border.left + border.right + padding.left + padding.right);
|
||||
mMaxHeight -= (border.top + border.bottom + padding.top + padding.bottom);
|
||||
|
||||
// Now the scrolledAreaWidth and scrolledAreaHeight are exactly
|
||||
// wide and high enough to enclose their contents
|
||||
|
||||
PRBool isInDropDownMode = IsInDropDownMode();
|
||||
|
||||
scrolledAreaWidth -= (border.left + border.right + padding.left + padding.right);
|
||||
scrolledAreaHeight -= (border.top + border.bottom + padding.top + padding.bottom);
|
||||
|
||||
nscoord visibleWidth = 0;
|
||||
if (isInDropDownMode) {
|
||||
// Calculate visible width for dropdown
|
||||
if (NS_UNCONSTRAINEDSIZE == aReflowState.mComputedWidth) {
|
||||
visibleWidth = scrolledAreaWidth;
|
||||
} else {
|
||||
visibleWidth = aReflowState.mComputedWidth - (border.left + border.right);
|
||||
if (visibleWidth < scrolledAreaWidth) {
|
||||
visibleWidth = scrolledAreaWidth;
|
||||
}
|
||||
visibleWidth = aReflowState.mComputedWidth;
|
||||
visibleWidth -= (border.left + border.right + padding.left + padding.right);
|
||||
//scrolledAreaHeight -= (border.top + border.bottom + padding.top + padding.bottom);
|
||||
}
|
||||
} else {
|
||||
if (NS_UNCONSTRAINEDSIZE == aReflowState.mComputedWidth) {
|
||||
|
@ -457,7 +485,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
//visibleWidth -= (border.left + border.right + padding.left + padding.right);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Determine if a scrollbar will be needed, If so we need to add
|
||||
// enough the width to allow for the scrollbar.
|
||||
// The scrollbar will be needed under two conditions:
|
||||
|
@ -487,7 +515,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
visibleHeight = scrolledAreaHeight;
|
||||
|
||||
if (visibleHeight > (kMaxDropDownRows * heightOfARow)) {
|
||||
visibleHeight = (kMaxDropDownRows * heightOfARow);
|
||||
visibleHeight = (kMaxDropDownRows * heightOfARow);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -511,7 +539,6 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// There are no items in the list
|
||||
// but we want to include space for the scrollbars
|
||||
// So fake like we will need scrollbars also
|
||||
|
@ -524,13 +551,9 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
needsVerticalScrollbar = PR_TRUE;
|
||||
}
|
||||
|
||||
if (needsVerticalScrollbar && !isInDropDownMode) {
|
||||
visibleWidth += scrollbarWidth;
|
||||
if (needsVerticalScrollbar) {
|
||||
mIsScrollbarVisible = PR_TRUE; // XXX temp code
|
||||
} else {
|
||||
if (!isInDropDownMode) {
|
||||
visibleWidth += scrollbarWidth;
|
||||
}
|
||||
mIsScrollbarVisible = PR_FALSE; // XXX temp code
|
||||
}
|
||||
|
||||
|
@ -549,6 +572,10 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
if (NS_UNCONSTRAINEDSIZE == aReflowState.mComputedWidth) {
|
||||
visibleWidth += (border.left + border.right + padding.left + padding.right);
|
||||
}
|
||||
|
||||
// Do a second reflow with the adjusted width and height settings
|
||||
// This sets up all of the frames with the correct width and height.
|
||||
secondPassState.mComputedWidth = visibleWidth;
|
||||
|
@ -562,7 +589,6 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
aDesiredSize.maxElementSize->width = aDesiredSize.width;
|
||||
aDesiredSize.maxElementSize->height = aDesiredSize.height;
|
||||
}
|
||||
//printf("List: aDesiredSize %d %d\n", aDesiredSize.width, aDesiredSize.height);
|
||||
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
|
||||
|
@ -581,6 +607,8 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
#endif
|
||||
|
||||
nsFormControlFrame::SetupCachedSizes(mCacheSize, mCachedMaxElementSize, aDesiredSize);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -245,6 +245,10 @@ protected:
|
|||
// XXX temprary only until full system mouse capture works
|
||||
PRBool mIsScrollbarVisible;
|
||||
|
||||
//Resize Reflow OpitmizationSize;
|
||||
nsSize mCacheSize;
|
||||
nsSize mCachedMaxElementSize;
|
||||
|
||||
private:
|
||||
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
|
||||
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
|
||||
|
|
|
@ -670,39 +670,12 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
#endif
|
||||
|
||||
|
||||
// XXX Temporary Fix for too many resize reflows
|
||||
#ifdef OPTIMIZE_RESIZE_RELOW
|
||||
if (aReflowState.reason == eReflowReason_Resize) {
|
||||
if (NS_UNCONSTRAINEDSIZE == aReflowState.mComputedWidth &&
|
||||
NS_UNCONSTRAINEDSIZE == aReflowState.mComputedHeight) {
|
||||
|
||||
if (mCacheSize.width > -1 && mCacheSize.height > -1) {
|
||||
aDesiredSize.width = mCacheSize.width;
|
||||
aDesiredSize.height = mCacheSize.height;
|
||||
if (aDesiredSize.maxElementSize != nsnull) {
|
||||
aDesiredSize.maxElementSize->width = mCachedMaxElementSize.width;
|
||||
aDesiredSize.maxElementSize->height = mCachedMaxElementSize.height;
|
||||
}
|
||||
aDesiredSize.ascent = aDesiredSize.height;
|
||||
aDesiredSize.descent = 0;
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;
|
||||
}
|
||||
} else {
|
||||
if (mCacheSize.width == aReflowState.mComputedWidth &&
|
||||
mCacheSize.height == aReflowState.mComputedHeight) {
|
||||
if (aDesiredSize.maxElementSize != nsnull) {
|
||||
aDesiredSize.maxElementSize->width = mCachedMaxElementSize.width;
|
||||
aDesiredSize.maxElementSize->height = mCachedMaxElementSize.height;
|
||||
}
|
||||
aDesiredSize.ascent = aDesiredSize.height;
|
||||
aDesiredSize.descent = 0;
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
nsresult skiprv = nsFormControlFrame::SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext,
|
||||
aDesiredSize, aReflowState, aStatus);
|
||||
if (NS_SUCCEEDED(skiprv)) {
|
||||
return skiprv;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsIFrame* buttonFrame = GetButtonFrame(aPresContext);
|
||||
|
@ -759,11 +732,6 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
displayFrame->GetRect(displayRect);
|
||||
buttonFrame->GetRect(buttonRect);
|
||||
if ((oldDisplayRect == displayRect) && (oldButtonRect == buttonRect)) {
|
||||
// Reposition the popup.
|
||||
//nsRect absoluteTwips;
|
||||
//nsRect absolutePixels;
|
||||
//GetAbsoluteFramePosition(aPresContext, displayFrame, absoluteTwips, absolutePixels);
|
||||
//PositionDropdown(aPresContext, displayRect.height, absoluteTwips, absolutePixels);
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
return rv;
|
||||
}
|
||||
|
@ -774,6 +742,18 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
firstPassState.reflowCommand = nsnull;
|
||||
}
|
||||
|
||||
// the default size of the of scrollbar
|
||||
// that will be the default width of the dropdown button
|
||||
// the height will be the height of the text
|
||||
nscoord scrollbarWidth = -1;
|
||||
nsCOMPtr<nsIDeviceContext> dx;
|
||||
aPresContext->GetDeviceContext(getter_AddRefs(dx));
|
||||
if (dx) {
|
||||
float sbWidth;
|
||||
float sbHeight;
|
||||
dx->GetScrollBarDimensions(sbWidth, sbHeight);
|
||||
scrollbarWidth = (nscoord)sbWidth;
|
||||
}
|
||||
|
||||
//Set the desired size for the button and display frame
|
||||
if (NS_UNCONSTRAINEDSIZE == firstPassState.mComputedWidth) {
|
||||
|
@ -796,28 +776,35 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
mListControlFrame->GetNumberOfOptions(&length);
|
||||
dropdownFrame->GetRect(dropdownRect);
|
||||
|
||||
const nsStyleSpacing* dropSpacing;
|
||||
dropdownFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)dropSpacing);
|
||||
nsMargin dropBorderPadding;
|
||||
dropBorderPadding.SizeTo(0, 0, 0, 0);
|
||||
dropSpacing->CalcBorderPaddingFor(dropdownFrame, dropBorderPadding);
|
||||
dropdownRect.width -= (dropBorderPadding.left + dropBorderPadding.right);
|
||||
|
||||
// Get maximum size and height of a option in the dropdown
|
||||
mListControlFrame->GetMaximumSize(size);
|
||||
|
||||
// Set width of display to match width of the drop down
|
||||
SetChildFrameSize(displayFrame, dropdownRect.width, size.height);
|
||||
if (scrollbarWidth > 0) {
|
||||
size.width = scrollbarWidth;
|
||||
}
|
||||
const nsStyleSpacing* dspSpacing;
|
||||
displayFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)dspSpacing);
|
||||
nsMargin dspBorderPadding;
|
||||
dspBorderPadding.SizeTo(0, 0, 0, 0);
|
||||
dspSpacing->CalcBorderPaddingFor(displayFrame, dspBorderPadding);
|
||||
|
||||
// Set width of display to match width of the drop down
|
||||
SetChildFrameSize(displayFrame, dropdownRect.width-size.width+dspBorderPadding.left+dspBorderPadding.right,
|
||||
size.height+dspBorderPadding.top+dspBorderPadding.bottom);
|
||||
|
||||
// the default size of the of scrollbar
|
||||
// that will be the default width of the dropdown button
|
||||
// the height will be the height of the text
|
||||
nsCOMPtr<nsIDeviceContext> dx;
|
||||
aPresContext->GetDeviceContext(getter_AddRefs(dx));
|
||||
if (dx) {
|
||||
float sbWidth;
|
||||
float sbHeight;
|
||||
dx->GetScrollBarDimensions(sbWidth, sbHeight);
|
||||
size.width = (nscoord)sbWidth;
|
||||
}
|
||||
// Size the button
|
||||
SetChildFrameSize(buttonFrame, size.width, size.height);
|
||||
|
||||
// Reflow display + button
|
||||
nsAreaFrame::Reflow(aPresContext, aDesiredSize, firstPassState, aStatus);
|
||||
|
||||
displayFrame->GetRect(displayRect);
|
||||
buttonFrame->GetRect(buttonRect);
|
||||
buttonRect.y = displayRect.y;
|
||||
|
@ -831,6 +818,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
if (maxElementSize) {
|
||||
delete maxElementSize;
|
||||
}
|
||||
|
||||
} else {
|
||||
// A width has been specified for the select.
|
||||
// Make the display frame's width + button frame width = the width specified.
|
||||
|
@ -840,30 +828,37 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
nsSize size;
|
||||
mListControlFrame->GetMaximumSize(size);
|
||||
|
||||
// Size the button to be the same height as the displayFrame
|
||||
SetChildFrameSize(buttonFrame, size.height, size.height);
|
||||
if (scrollbarWidth > 0) {
|
||||
size.width = scrollbarWidth;
|
||||
}
|
||||
// Size the button to be the same as the scrollbar width
|
||||
SetChildFrameSize(buttonFrame, size.width, size.height);
|
||||
|
||||
// Compute display width
|
||||
// Since the button's width is the same as its height
|
||||
// we subtract size.height (the width)
|
||||
nscoord displayWidth = firstPassState.mComputedWidth - size.height;
|
||||
nscoord displayWidth = firstPassState.mComputedWidth - size.width;
|
||||
// nsAreaFrame::Reflow adds in the border and padding so we need to remove it
|
||||
displayWidth -= borderPadding.left + borderPadding.right;
|
||||
//displayWidth -= borderPadding.left + borderPadding.right;
|
||||
|
||||
// Set the displayFrame to match the displayWidth computed above
|
||||
// Set the displayFrame to match the displayWidth computed above
|
||||
SetChildFrameSize(displayFrame, displayWidth, size.height);
|
||||
|
||||
// Reflow again with the width of the display frame set.
|
||||
// Reflow again with the width of the display frame set.
|
||||
nsAreaFrame::Reflow(aPresContext, aDesiredSize, firstPassState, aStatus);
|
||||
// nsAreaFrame::Reflow adds in the border and padding so we need to remove it
|
||||
// XXX rods - this hould not be subtracted in
|
||||
//aDesiredSize.width -= borderPadding.left + borderPadding.right;
|
||||
//aDesiredSize.width += borderPadding.left + borderPadding.right;
|
||||
|
||||
// Reflow the dropdown list to match the width of the display + button
|
||||
ReflowComboChildFrame(dropdownFrame, aPresContext, dropdownDesiredSize, firstPassState, aStatus, aDesiredSize.width, NS_UNCONSTRAINEDSIZE);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Set the max element size to be the same as the desired element size.
|
||||
if (nsnull != aDesiredSize.maxElementSize) {
|
||||
aDesiredSize.maxElementSize->width = aDesiredSize.width;
|
||||
aDesiredSize.maxElementSize->height = aDesiredSize.height;
|
||||
}
|
||||
|
||||
nsRect absoluteTwips;
|
||||
nsRect absolutePixels;
|
||||
GetAbsoluteFramePosition(aPresContext, this, absoluteTwips, absolutePixels);
|
||||
|
@ -871,19 +866,10 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
#if 0
|
||||
COMPARE_QUIRK_SIZE("nsComboboxControlFrame", 56, 22)
|
||||
#endif
|
||||
|
||||
// XXX Temporary Fix for too many resize reflows
|
||||
#ifdef OPTIMIZE_RESIZE_RELOW
|
||||
mCacheSize.width = aDesiredSize.width;
|
||||
mCacheSize.height = aDesiredSize.height;
|
||||
if (aDesiredSize.maxElementSize != nsnull) {
|
||||
mCachedMaxElementSize.width = aDesiredSize.maxElementSize->width;
|
||||
mCachedMaxElementSize.height = aDesiredSize.maxElementSize->height;
|
||||
}
|
||||
COMPARE_QUIRK_SIZE("nsComboboxControlFrame", 127, 22)
|
||||
#endif
|
||||
|
||||
nsFormControlFrame::SetupCachedSizes(mCacheSize, mCachedMaxElementSize, aDesiredSize);
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
#ifndef nsComboboxControlFrame_h___
|
||||
#define nsComboboxControlFrame_h___
|
||||
|
||||
#define OPTIMIZE_RESIZE_RELOW
|
||||
|
||||
#include "nsAreaFrame.h"
|
||||
#include "nsIFormControlFrame.h"
|
||||
#include "nsIComboboxControlFrame.h"
|
||||
|
@ -211,11 +209,9 @@ protected:
|
|||
nsIListControlFrame * mListControlFrame; // ListControl Interface for the dropdown frame
|
||||
PRBool mIgnoreFocus; // Tells the combo to ignore all focus notifications
|
||||
|
||||
// XXX Temporary Fix for too many resize reflows
|
||||
#ifdef OPTIMIZE_RESIZE_RELOW
|
||||
//Resize Reflow OpitmizationSize;
|
||||
nsSize mCacheSize;
|
||||
nsSize mCachedMaxElementSize;
|
||||
#endif
|
||||
|
||||
private:
|
||||
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
|
||||
|
|
|
@ -112,6 +112,11 @@ nsListControlFrame::nsListControlFrame()
|
|||
mIsAllContentHere = PR_FALSE;
|
||||
mIsAllFramesHere = PR_FALSE;
|
||||
mHasBeenInitialized = PR_FALSE;
|
||||
|
||||
mCacheSize.width = -1;
|
||||
mCacheSize.height = -1;
|
||||
mCachedMaxElementSize.width = -1;
|
||||
mCachedMaxElementSize.height = -1;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -270,6 +275,13 @@ nsresult nsListControlFrame::CountAllChild(nsIDOMNode * aNode, PRInt32& aCount)
|
|||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
PRInt32 GetVal(PRInt32 aVal)
|
||||
{
|
||||
return aVal == NS_UNCONSTRAINEDSIZE?-1:aVal;
|
||||
}
|
||||
static int cnt = 0;
|
||||
*/
|
||||
//---------------------------------------------------------
|
||||
// Reflow is overriden to constrain the listbox height to the number of rows and columns
|
||||
// specified.
|
||||
|
@ -290,6 +302,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
#endif // DEBUG_rodsXXX
|
||||
|
||||
|
||||
#if 0
|
||||
// reflow optimization - why reflow if all the contents
|
||||
// and frames aren't there yet
|
||||
|
@ -331,7 +344,24 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
shell->ExitReflowLock(PR_TRUE, PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 1
|
||||
nsresult skiprv = nsFormControlFrame::SkipResizeReflow(mCacheSize, mCachedMaxElementSize, aPresContext,
|
||||
aDesiredSize, aReflowState, aStatus);
|
||||
if (NS_SUCCEEDED(skiprv)) {
|
||||
/*printf("%3d Skipping: %4d,%4d %4d,%4d %4d,%4d %4d,%4d\n", cnt++, GetVal(aReflowState.mComputedWidth), GetVal(aReflowState.mComputedHeight),
|
||||
GetVal(aReflowState.availableWidth), GetVal(aReflowState.availableHeight),
|
||||
GetVal(aReflowState.mComputedMaxWidth), GetVal(aReflowState.mComputedMaxHeight),
|
||||
aDesiredSize.width, aDesiredSize.height);
|
||||
*/
|
||||
return skiprv;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
printf("%3d Not Skip: %4d,%4d %4d,%4d %4d,%4d", cnt++, GetVal(aReflowState.mComputedWidth), GetVal(aReflowState.mComputedHeight),
|
||||
GetVal(aReflowState.availableWidth), GetVal(aReflowState.availableHeight),
|
||||
GetVal(aReflowState.mComputedMaxWidth), GetVal(aReflowState.mComputedMaxHeight));
|
||||
*/
|
||||
// Strategy: Let the inherited reflow happen as though the width and height of the
|
||||
// ScrollFrame are big enough to allow the listbox to
|
||||
// shrink to fit the longest option element line in the list.
|
||||
|
@ -395,7 +425,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
// to the maxElementSize, so these need to be subtracted
|
||||
nscoord scrolledAreaWidth = scrolledAreaDesiredSize.maxElementSize->width;
|
||||
nscoord scrolledAreaHeight = scrolledAreaDesiredSize.height;
|
||||
|
||||
//printf("(%d) ", scrolledAreaWidth);
|
||||
// Keep the oringal values
|
||||
mMaxWidth = scrolledAreaWidth;
|
||||
mMaxHeight = scrolledAreaDesiredSize.maxElementSize->height;
|
||||
|
@ -413,10 +443,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
nscoord scrollbarWidth = NSToCoordRound(sbWidth);
|
||||
//nscoord scrollbarHeight = NSToCoordRound(sbHeight);
|
||||
|
||||
// Subtract out the scrollbar width
|
||||
scrolledAreaWidth -= scrollbarWidth;
|
||||
|
||||
// Subtract out the borders
|
||||
// Subtract out the borders
|
||||
nsMargin border;
|
||||
if (!aReflowState.mStyleSpacing->GetBorder(border)) {
|
||||
NS_NOTYETIMPLEMENTED("percentage border");
|
||||
|
@ -429,24 +456,25 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
padding.SizeTo(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
scrolledAreaWidth -= (border.left + border.right + padding.left + padding.right);
|
||||
scrolledAreaHeight -= (border.top + border.bottom);
|
||||
mMaxWidth -= (border.left + border.right + padding.left + padding.right);
|
||||
mMaxHeight -= (border.top + border.bottom + padding.top + padding.bottom);
|
||||
|
||||
// Now the scrolledAreaWidth and scrolledAreaHeight are exactly
|
||||
// wide and high enough to enclose their contents
|
||||
|
||||
PRBool isInDropDownMode = IsInDropDownMode();
|
||||
|
||||
scrolledAreaWidth -= (border.left + border.right + padding.left + padding.right);
|
||||
scrolledAreaHeight -= (border.top + border.bottom + padding.top + padding.bottom);
|
||||
|
||||
nscoord visibleWidth = 0;
|
||||
if (isInDropDownMode) {
|
||||
// Calculate visible width for dropdown
|
||||
if (NS_UNCONSTRAINEDSIZE == aReflowState.mComputedWidth) {
|
||||
visibleWidth = scrolledAreaWidth;
|
||||
} else {
|
||||
visibleWidth = aReflowState.mComputedWidth - (border.left + border.right);
|
||||
if (visibleWidth < scrolledAreaWidth) {
|
||||
visibleWidth = scrolledAreaWidth;
|
||||
}
|
||||
visibleWidth = aReflowState.mComputedWidth;
|
||||
visibleWidth -= (border.left + border.right + padding.left + padding.right);
|
||||
//scrolledAreaHeight -= (border.top + border.bottom + padding.top + padding.bottom);
|
||||
}
|
||||
} else {
|
||||
if (NS_UNCONSTRAINEDSIZE == aReflowState.mComputedWidth) {
|
||||
|
@ -457,7 +485,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
//visibleWidth -= (border.left + border.right + padding.left + padding.right);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Determine if a scrollbar will be needed, If so we need to add
|
||||
// enough the width to allow for the scrollbar.
|
||||
// The scrollbar will be needed under two conditions:
|
||||
|
@ -487,7 +515,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
visibleHeight = scrolledAreaHeight;
|
||||
|
||||
if (visibleHeight > (kMaxDropDownRows * heightOfARow)) {
|
||||
visibleHeight = (kMaxDropDownRows * heightOfARow);
|
||||
visibleHeight = (kMaxDropDownRows * heightOfARow);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -511,7 +539,6 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// There are no items in the list
|
||||
// but we want to include space for the scrollbars
|
||||
// So fake like we will need scrollbars also
|
||||
|
@ -524,13 +551,9 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
needsVerticalScrollbar = PR_TRUE;
|
||||
}
|
||||
|
||||
if (needsVerticalScrollbar && !isInDropDownMode) {
|
||||
visibleWidth += scrollbarWidth;
|
||||
if (needsVerticalScrollbar) {
|
||||
mIsScrollbarVisible = PR_TRUE; // XXX temp code
|
||||
} else {
|
||||
if (!isInDropDownMode) {
|
||||
visibleWidth += scrollbarWidth;
|
||||
}
|
||||
mIsScrollbarVisible = PR_FALSE; // XXX temp code
|
||||
}
|
||||
|
||||
|
@ -549,6 +572,10 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
if (NS_UNCONSTRAINEDSIZE == aReflowState.mComputedWidth) {
|
||||
visibleWidth += (border.left + border.right + padding.left + padding.right);
|
||||
}
|
||||
|
||||
// Do a second reflow with the adjusted width and height settings
|
||||
// This sets up all of the frames with the correct width and height.
|
||||
secondPassState.mComputedWidth = visibleWidth;
|
||||
|
@ -562,7 +589,6 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
aDesiredSize.maxElementSize->width = aDesiredSize.width;
|
||||
aDesiredSize.maxElementSize->height = aDesiredSize.height;
|
||||
}
|
||||
//printf("List: aDesiredSize %d %d\n", aDesiredSize.width, aDesiredSize.height);
|
||||
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
|
||||
|
@ -581,6 +607,8 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
|||
}
|
||||
#endif
|
||||
|
||||
nsFormControlFrame::SetupCachedSizes(mCacheSize, mCachedMaxElementSize, aDesiredSize);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -245,6 +245,10 @@ protected:
|
|||
// XXX temprary only until full system mouse capture works
|
||||
PRBool mIsScrollbarVisible;
|
||||
|
||||
//Resize Reflow OpitmizationSize;
|
||||
nsSize mCacheSize;
|
||||
nsSize mCachedMaxElementSize;
|
||||
|
||||
private:
|
||||
NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; }
|
||||
NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; }
|
||||
|
|
Загрузка…
Ссылка в новой задаче