Now only doing 1 reflow for each reflow request in the ListControlFrame
for initial and full resize reflows Bug 69869 r=kmcclusk sr=attinasi git-svn-id: svn://10.0.0.236/trunk@87751 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -60,8 +60,10 @@
|
||||
#include "nsINodeInfo.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsListControlFrame.h"
|
||||
#include "nsIElementFactory.h"
|
||||
#include "nsContentCID.h"
|
||||
|
||||
static NS_DEFINE_CID(kTextNodeCID, NS_TEXTNODE_CID);
|
||||
static NS_DEFINE_CID(kHTMLElementFactoryCID, NS_HTML_ELEMENT_FACTORY_CID);
|
||||
|
||||
@@ -94,6 +96,7 @@ const PRInt32 kSizeNotSet = -1;
|
||||
|
||||
// static class data member for Bug 32920
|
||||
nsComboboxControlFrame * nsComboboxControlFrame::mFocused = nsnull;
|
||||
nscoord nsComboboxControlFrame::mCachedScrollbarWidth = kSizeNotSet;
|
||||
|
||||
nsresult
|
||||
NS_NewComboboxControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRUint32 aStateFlags)
|
||||
@@ -1205,24 +1208,25 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
// 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) {
|
||||
// Get the width in Device pixels (in this case screen)
|
||||
SystemAttrStruct info;
|
||||
dx->GetSystemAttribute(eSystemAttr_Size_ScrollbarWidth, &info);
|
||||
// Get the pixels to twips conversion for the current device (screen or printer)
|
||||
float p2t;
|
||||
aPresContext->GetPixelsToTwips(&p2t);
|
||||
// Get the scale factor for mapping from one device (screen)
|
||||
// to another device (screen or printer)
|
||||
// Typically when it is a screen the scale 1.0
|
||||
// when it is a printer is could be anything
|
||||
float scale;
|
||||
dx->GetCanonicalPixelScale(scale);
|
||||
scrollbarWidth = NSIntPixelsToTwips(info.mSize, p2t*scale);
|
||||
}
|
||||
if (mCachedScrollbarWidth == kSizeNotSet) {
|
||||
nsCOMPtr<nsIDeviceContext> dx;
|
||||
aPresContext->GetDeviceContext(getter_AddRefs(dx));
|
||||
if (dx) {
|
||||
// Get the width in Device pixels (in this case screen)
|
||||
SystemAttrStruct info;
|
||||
dx->GetSystemAttribute(eSystemAttr_Size_ScrollbarWidth, &info);
|
||||
// Get the pixels to twips conversion for the current device (screen or printer)
|
||||
float p2t;
|
||||
aPresContext->GetPixelsToTwips(&p2t);
|
||||
// Get the scale factor for mapping from one device (screen)
|
||||
// to another device (screen or printer)
|
||||
// Typically when it is a screen the scale 1.0
|
||||
// when it is a printer is could be anything
|
||||
float scale;
|
||||
dx->GetCanonicalPixelScale(scale);
|
||||
mCachedScrollbarWidth = NSIntPixelsToTwips(info.mSize, p2t*scale);
|
||||
}
|
||||
}
|
||||
|
||||
// set up a new reflow state for use throughout
|
||||
nsHTMLReflowState firstPassState(aReflowState);
|
||||
@@ -1257,7 +1261,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
REFLOW_DEBUG_MSG("------------Reflowing AreaFrame and bailing----\n\n");
|
||||
ReflowCombobox(aPresContext, firstPassState, aDesiredSize, aStatus,
|
||||
mDisplayFrame, mButtonFrame, mItemDisplayWidth,
|
||||
scrollbarWidth, borderPadding);
|
||||
mCachedScrollbarWidth, borderPadding);
|
||||
REFLOW_COUNTER();
|
||||
UNCONSTRAINED_CHECK();
|
||||
REFLOW_DEBUG_MSG3("&** Done nsCCF DW: %d DH: %d\n\n", PX(aDesiredSize.width), PX(aDesiredSize.height));
|
||||
@@ -1310,7 +1314,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
// Do simple reflow and bail out
|
||||
ReflowCombobox(aPresContext, firstPassState, aDesiredSize, aStatus,
|
||||
mDisplayFrame, mButtonFrame,
|
||||
mItemDisplayWidth, scrollbarWidth, borderPadding, kSizeNotSet, PR_TRUE);
|
||||
mItemDisplayWidth, mCachedScrollbarWidth, borderPadding, kSizeNotSet, PR_TRUE);
|
||||
REFLOW_DEBUG_MSG3("+** Done nsCCF DW: %d DH: %d\n\n", PX(aDesiredSize.width), PX(aDesiredSize.height));
|
||||
REFLOW_COUNTER();
|
||||
UNCONSTRAINED_CHECK();
|
||||
@@ -1379,11 +1383,18 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
if ((mCachedUncDropdownSize.width == kSizeNotSet &&
|
||||
mCachedUncDropdownSize.height == kSizeNotSet) || forceReflow) {
|
||||
REFLOW_DEBUG_MSG3("---Re %d,%d\n", PX(mCachedUncDropdownSize.width), PX(mCachedUncDropdownSize.height));
|
||||
|
||||
// Tell it we are doing the first pass, which means it will
|
||||
// do the unconstained reflow and skip the second reflow this time around
|
||||
nsListControlFrame * lcf = NS_STATIC_CAST(nsListControlFrame*, mDropdownFrame);
|
||||
lcf->SetPassId(1);
|
||||
// A width has not been specified for the select so size the display area
|
||||
// to match the width of the longest item in the drop-down list. The dropdown
|
||||
// list has already been reflowed and sized to shrink around its contents above.
|
||||
ReflowComboChildFrame(mDropdownFrame, aPresContext, dropdownDesiredSize, firstPassState,
|
||||
aStatus, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
|
||||
lcf->SetPassId(0); // reset it back
|
||||
|
||||
if (forceReflow) {
|
||||
mCachedUncDropdownSize.width = dropdownDesiredSize.width;
|
||||
mCachedUncDropdownSize.height = dropdownDesiredSize.height;
|
||||
@@ -1466,8 +1477,8 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
|
||||
// the variable "size" will now be
|
||||
// the default size of the dropdown btn
|
||||
if (scrollbarWidth > 0) {
|
||||
size.width = scrollbarWidth;
|
||||
if (mCachedScrollbarWidth > 0) {
|
||||
size.width = mCachedScrollbarWidth;
|
||||
}
|
||||
|
||||
// Get the border and padding for the dropdown
|
||||
@@ -1524,7 +1535,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
|
||||
// this reflows and makes and last minute adjustments
|
||||
ReflowCombobox(aPresContext, firstPassState, aDesiredSize, aStatus,
|
||||
mDisplayFrame, mButtonFrame, mItemDisplayWidth, scrollbarWidth,
|
||||
mDisplayFrame, mButtonFrame, mItemDisplayWidth, mCachedScrollbarWidth,
|
||||
borderPadding, size.height);
|
||||
|
||||
// The dropdown was reflowed UNCONSTRAINED before, now we need to check to see
|
||||
@@ -1534,17 +1545,21 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
// than for any particular item in the dropdown. So, if the new size of combobox
|
||||
// is smaller than the dropdown, that is OK, The dropdown MUST always be either the same
|
||||
//size as the combo or larger if necessary
|
||||
#if 1
|
||||
if (aDesiredSize.width > dropdownDesiredSize.width) {
|
||||
if (eReflowReason_Initial == firstPassState.reason) {
|
||||
firstPassState.reason = eReflowReason_Resize;
|
||||
}
|
||||
REFLOW_DEBUG_MSG3("*** Reflowing ListBox to width: %d it was %d\n", PX(aDesiredSize.width), PX(dropdownDesiredSize.width));
|
||||
|
||||
// Tell it we are doing the second pass, which means we will skip
|
||||
// doing the unconstained reflow, we already know that size
|
||||
nsListControlFrame * lcf = NS_STATIC_CAST(nsListControlFrame*, mDropdownFrame);
|
||||
lcf->SetPassId(2);
|
||||
// Reflow the dropdown list to match the width of the display + button
|
||||
ReflowComboChildFrame(mDropdownFrame, aPresContext, dropdownDesiredSize, firstPassState, aStatus,
|
||||
aDesiredSize.width, NS_UNCONSTRAINEDSIZE);
|
||||
lcf->SetPassId(0); // reset it back
|
||||
}
|
||||
#endif
|
||||
|
||||
#else // DO_NEW_REFLOW
|
||||
|
||||
@@ -1573,7 +1588,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
|
||||
// this reflows and makes and last minute adjustments
|
||||
ReflowCombobox(aPresContext, firstPassState, aDesiredSize, aStatus,
|
||||
mDisplayFrame, mButtonFrame, mItemDisplayWidth, scrollbarWidth,
|
||||
mDisplayFrame, mButtonFrame, mItemDisplayWidth, mCachedScrollbarWidth,
|
||||
borderPadding,
|
||||
aDesiredSize.height- borderPadding.top - borderPadding.bottom -
|
||||
dspBorderPadding.top - dspBorderPadding.bottom);
|
||||
|
||||
@@ -278,6 +278,7 @@ protected:
|
||||
// static class data member for Bug 32920
|
||||
// only one control can be focused at a time
|
||||
static nsComboboxControlFrame * mFocused;
|
||||
static nscoord mCachedScrollbarWidth;
|
||||
|
||||
#ifdef DO_REFLOW_COUNTER
|
||||
PRInt32 mReflowId;
|
||||
|
||||
@@ -242,6 +242,7 @@ nsListControlFrame::nsListControlFrame()
|
||||
mCachedUnconstrainedSize.height = -1;
|
||||
|
||||
mOverrideReflowOpt = PR_FALSE;
|
||||
mPassId = 0;
|
||||
|
||||
REFLOW_COUNTER_INIT()
|
||||
}
|
||||
@@ -611,62 +612,46 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
nsresult res = nsScrollFrame::Reflow(aPresContext,
|
||||
scrolledAreaDesiredSize,
|
||||
firstPassState,
|
||||
aStatus);
|
||||
if (NS_FAILED(res)) {
|
||||
NS_ASSERTION(aDesiredSize.width < 100000, "Width is still NS_UNCONSTRAINEDSIZE");
|
||||
NS_ASSERTION(aDesiredSize.height < 100000, "Height is still NS_UNCONSTRAINEDSIZE");
|
||||
return res;
|
||||
if (mPassId == 0 || mPassId == 1) {
|
||||
nsresult res = nsScrollFrame::Reflow(aPresContext,
|
||||
scrolledAreaDesiredSize,
|
||||
firstPassState,
|
||||
aStatus);
|
||||
if (NS_FAILED(res)) {
|
||||
NS_ASSERTION(aDesiredSize.width < 100000, "Width is still NS_UNCONSTRAINEDSIZE");
|
||||
NS_ASSERTION(aDesiredSize.height < 100000, "Height is still NS_UNCONSTRAINEDSIZE");
|
||||
return res;
|
||||
}
|
||||
mCachedUnconstrainedSize.width = scrolledAreaDesiredSize.width;
|
||||
mCachedUnconstrainedSize.height = scrolledAreaDesiredSize.height;
|
||||
mCachedDesiredMaxSize.width = scrolledAreaDesiredSize.maxElementSize->width;
|
||||
mCachedDesiredMaxSize.height = scrolledAreaDesiredSize.maxElementSize->height;
|
||||
} else {
|
||||
scrolledAreaDesiredSize.width = mCachedUnconstrainedSize.width;
|
||||
scrolledAreaDesiredSize.height = mCachedUnconstrainedSize.height;
|
||||
scrolledAreaDesiredSize.maxElementSize->width = mCachedDesiredMaxSize.width;
|
||||
scrolledAreaDesiredSize.maxElementSize->height = mCachedDesiredMaxSize.height;
|
||||
}
|
||||
|
||||
nsIScrollableFrame * scrollableFrame = nsnull;
|
||||
nsRect scrolledRect;
|
||||
if (NS_SUCCEEDED(QueryInterface(NS_GET_IID(nsIScrollableFrame), (void**)&scrollableFrame))) {
|
||||
nsIFrame * scrolledFrame;
|
||||
scrollableFrame->GetScrolledFrame(aPresContext, scrolledFrame);
|
||||
NS_ASSERTION(scrolledFrame != nsnull, "Must have scrollable frame");
|
||||
scrolledFrame->GetRect(scrolledRect);
|
||||
} else {
|
||||
NS_ASSERTION(scrollableFrame != nsnull, "Must have scrollableFrame frame");
|
||||
}
|
||||
// Compute the bounding box of the contents of the list using the area
|
||||
// calculated by the first reflow as a starting point.
|
||||
//
|
||||
// The nsScrollFrame::REflow adds in the scrollbar width and border dimensions
|
||||
// to the maxElementSize, so these need to be subtracted
|
||||
nscoord scrolledAreaWidth = scrolledAreaDesiredSize.maxElementSize->width;
|
||||
nscoord scrolledAreaHeight = scrolledAreaDesiredSize.height;
|
||||
nscoord scrolledAreaWidth = scrolledAreaDesiredSize.maxElementSize->width -
|
||||
(aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right);
|
||||
nscoord scrolledAreaHeight = scrolledAreaDesiredSize.height -
|
||||
(aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom);
|
||||
|
||||
// Keep the oringal values
|
||||
// Set up max values
|
||||
mMaxWidth = scrolledAreaWidth;
|
||||
mMaxHeight = scrolledAreaDesiredSize.maxElementSize->height;
|
||||
|
||||
// The first reflow produces a box with the scrollbar width and borders
|
||||
// added in so we need to subtract them out.
|
||||
|
||||
// Retrieve the scrollbar's width and height
|
||||
float sbWidth = 0.0;
|
||||
float sbHeight = 0.0;;
|
||||
nsCOMPtr<nsIDeviceContext> dc;
|
||||
aPresContext->GetDeviceContext(getter_AddRefs(dc));
|
||||
dc->GetScrollBarDimensions(sbWidth, sbHeight);
|
||||
// Convert to nscoord's by rounding
|
||||
nscoord scrollbarWidth = NSToCoordRound(sbWidth);
|
||||
//nscoord scrollbarHeight = NSToCoordRound(sbHeight);
|
||||
|
||||
mMaxWidth -= aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right;
|
||||
mMaxHeight -= aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom;
|
||||
mMaxHeight = scrolledAreaDesiredSize.maxElementSize->height -
|
||||
(aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom);
|
||||
|
||||
// Now the scrolledAreaWidth and scrolledAreaHeight are exactly
|
||||
// wide and high enough to enclose their contents
|
||||
|
||||
PRBool isInDropDownMode = IsInDropDownMode();
|
||||
|
||||
scrolledAreaWidth -= aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right;
|
||||
scrolledAreaHeight -= aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom;
|
||||
|
||||
nscoord visibleWidth = 0;
|
||||
if (isInDropDownMode) {
|
||||
if (NS_UNCONSTRAINEDSIZE == aReflowState.mComputedWidth) {
|
||||
@@ -679,7 +664,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
if (NS_UNCONSTRAINEDSIZE == aReflowState.mComputedWidth) {
|
||||
visibleWidth = scrolledAreaWidth;
|
||||
} else {
|
||||
visibleWidth = aReflowState.mComputedWidth;// - scrollbarWidth;
|
||||
visibleWidth = aReflowState.mComputedWidth;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -870,9 +855,16 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
secondPassState.mComputedHeight = visibleHeight;
|
||||
secondPassState.reason = eReflowReason_Resize;
|
||||
|
||||
nsScrollFrame::Reflow(aPresContext, aDesiredSize, secondPassState, aStatus);
|
||||
|
||||
if (mPassId == 0 || mPassId == 2) {
|
||||
nsScrollFrame::Reflow(aPresContext, aDesiredSize, secondPassState, aStatus);
|
||||
// Set the max element size to be the same as the desired element size.
|
||||
} else {
|
||||
aDesiredSize.width = visibleWidth;
|
||||
aDesiredSize.height = visibleHeight;
|
||||
aDesiredSize.ascent = aDesiredSize.height;
|
||||
aDesiredSize.descent = 0;
|
||||
}
|
||||
|
||||
if (nsnull != aDesiredSize.maxElementSize) {
|
||||
aDesiredSize.maxElementSize->width = aDesiredSize.width;
|
||||
aDesiredSize.maxElementSize->height = aDesiredSize.height;
|
||||
@@ -880,7 +872,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
|
||||
#ifdef DEBUG_rods
|
||||
#ifdef DEBUG_rodsX
|
||||
if (!isInDropDownMode) {
|
||||
PRInt32 numRows = 1;
|
||||
GetSizeAttribute(&numRows);
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_rods
|
||||
#define DO_REFLOW_DEBUG
|
||||
#define DO_REFLOW_COUNTER
|
||||
//#define DO_REFLOW_DEBUG
|
||||
//#define DO_REFLOW_COUNTER
|
||||
//#define DO_UNCONSTRAINED_CHECK
|
||||
//#define DO_PIXELS
|
||||
#endif
|
||||
@@ -290,6 +290,9 @@ public:
|
||||
nsCWeakReferent *WeakReferent()
|
||||
{ return &mWeakReferent; }
|
||||
|
||||
// Helper
|
||||
void SetPassId(PRInt16 aId) { mPassId = aId; }
|
||||
|
||||
protected:
|
||||
|
||||
NS_IMETHOD GetSelectedIndexFromDOM(PRInt32* aIndex); // from DOM
|
||||
@@ -402,6 +405,9 @@ protected:
|
||||
// XXX temprary only until full system mouse capture works
|
||||
PRBool mIsScrollbarVisible;
|
||||
|
||||
PRInt16 mPassId;
|
||||
nsSize mCachedDesiredMaxSize;
|
||||
|
||||
//Resize Reflow OpitmizationSize;
|
||||
nsSize mCacheSize;
|
||||
nsSize mCachedMaxElementSize;
|
||||
|
||||
@@ -60,8 +60,10 @@
|
||||
#include "nsINodeInfo.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsListControlFrame.h"
|
||||
#include "nsIElementFactory.h"
|
||||
#include "nsContentCID.h"
|
||||
|
||||
static NS_DEFINE_CID(kTextNodeCID, NS_TEXTNODE_CID);
|
||||
static NS_DEFINE_CID(kHTMLElementFactoryCID, NS_HTML_ELEMENT_FACTORY_CID);
|
||||
|
||||
@@ -94,6 +96,7 @@ const PRInt32 kSizeNotSet = -1;
|
||||
|
||||
// static class data member for Bug 32920
|
||||
nsComboboxControlFrame * nsComboboxControlFrame::mFocused = nsnull;
|
||||
nscoord nsComboboxControlFrame::mCachedScrollbarWidth = kSizeNotSet;
|
||||
|
||||
nsresult
|
||||
NS_NewComboboxControlFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame, PRUint32 aStateFlags)
|
||||
@@ -1205,24 +1208,25 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
// 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) {
|
||||
// Get the width in Device pixels (in this case screen)
|
||||
SystemAttrStruct info;
|
||||
dx->GetSystemAttribute(eSystemAttr_Size_ScrollbarWidth, &info);
|
||||
// Get the pixels to twips conversion for the current device (screen or printer)
|
||||
float p2t;
|
||||
aPresContext->GetPixelsToTwips(&p2t);
|
||||
// Get the scale factor for mapping from one device (screen)
|
||||
// to another device (screen or printer)
|
||||
// Typically when it is a screen the scale 1.0
|
||||
// when it is a printer is could be anything
|
||||
float scale;
|
||||
dx->GetCanonicalPixelScale(scale);
|
||||
scrollbarWidth = NSIntPixelsToTwips(info.mSize, p2t*scale);
|
||||
}
|
||||
if (mCachedScrollbarWidth == kSizeNotSet) {
|
||||
nsCOMPtr<nsIDeviceContext> dx;
|
||||
aPresContext->GetDeviceContext(getter_AddRefs(dx));
|
||||
if (dx) {
|
||||
// Get the width in Device pixels (in this case screen)
|
||||
SystemAttrStruct info;
|
||||
dx->GetSystemAttribute(eSystemAttr_Size_ScrollbarWidth, &info);
|
||||
// Get the pixels to twips conversion for the current device (screen or printer)
|
||||
float p2t;
|
||||
aPresContext->GetPixelsToTwips(&p2t);
|
||||
// Get the scale factor for mapping from one device (screen)
|
||||
// to another device (screen or printer)
|
||||
// Typically when it is a screen the scale 1.0
|
||||
// when it is a printer is could be anything
|
||||
float scale;
|
||||
dx->GetCanonicalPixelScale(scale);
|
||||
mCachedScrollbarWidth = NSIntPixelsToTwips(info.mSize, p2t*scale);
|
||||
}
|
||||
}
|
||||
|
||||
// set up a new reflow state for use throughout
|
||||
nsHTMLReflowState firstPassState(aReflowState);
|
||||
@@ -1257,7 +1261,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
REFLOW_DEBUG_MSG("------------Reflowing AreaFrame and bailing----\n\n");
|
||||
ReflowCombobox(aPresContext, firstPassState, aDesiredSize, aStatus,
|
||||
mDisplayFrame, mButtonFrame, mItemDisplayWidth,
|
||||
scrollbarWidth, borderPadding);
|
||||
mCachedScrollbarWidth, borderPadding);
|
||||
REFLOW_COUNTER();
|
||||
UNCONSTRAINED_CHECK();
|
||||
REFLOW_DEBUG_MSG3("&** Done nsCCF DW: %d DH: %d\n\n", PX(aDesiredSize.width), PX(aDesiredSize.height));
|
||||
@@ -1310,7 +1314,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
// Do simple reflow and bail out
|
||||
ReflowCombobox(aPresContext, firstPassState, aDesiredSize, aStatus,
|
||||
mDisplayFrame, mButtonFrame,
|
||||
mItemDisplayWidth, scrollbarWidth, borderPadding, kSizeNotSet, PR_TRUE);
|
||||
mItemDisplayWidth, mCachedScrollbarWidth, borderPadding, kSizeNotSet, PR_TRUE);
|
||||
REFLOW_DEBUG_MSG3("+** Done nsCCF DW: %d DH: %d\n\n", PX(aDesiredSize.width), PX(aDesiredSize.height));
|
||||
REFLOW_COUNTER();
|
||||
UNCONSTRAINED_CHECK();
|
||||
@@ -1379,11 +1383,18 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
if ((mCachedUncDropdownSize.width == kSizeNotSet &&
|
||||
mCachedUncDropdownSize.height == kSizeNotSet) || forceReflow) {
|
||||
REFLOW_DEBUG_MSG3("---Re %d,%d\n", PX(mCachedUncDropdownSize.width), PX(mCachedUncDropdownSize.height));
|
||||
|
||||
// Tell it we are doing the first pass, which means it will
|
||||
// do the unconstained reflow and skip the second reflow this time around
|
||||
nsListControlFrame * lcf = NS_STATIC_CAST(nsListControlFrame*, mDropdownFrame);
|
||||
lcf->SetPassId(1);
|
||||
// A width has not been specified for the select so size the display area
|
||||
// to match the width of the longest item in the drop-down list. The dropdown
|
||||
// list has already been reflowed and sized to shrink around its contents above.
|
||||
ReflowComboChildFrame(mDropdownFrame, aPresContext, dropdownDesiredSize, firstPassState,
|
||||
aStatus, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
|
||||
lcf->SetPassId(0); // reset it back
|
||||
|
||||
if (forceReflow) {
|
||||
mCachedUncDropdownSize.width = dropdownDesiredSize.width;
|
||||
mCachedUncDropdownSize.height = dropdownDesiredSize.height;
|
||||
@@ -1466,8 +1477,8 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
|
||||
// the variable "size" will now be
|
||||
// the default size of the dropdown btn
|
||||
if (scrollbarWidth > 0) {
|
||||
size.width = scrollbarWidth;
|
||||
if (mCachedScrollbarWidth > 0) {
|
||||
size.width = mCachedScrollbarWidth;
|
||||
}
|
||||
|
||||
// Get the border and padding for the dropdown
|
||||
@@ -1524,7 +1535,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
|
||||
// this reflows and makes and last minute adjustments
|
||||
ReflowCombobox(aPresContext, firstPassState, aDesiredSize, aStatus,
|
||||
mDisplayFrame, mButtonFrame, mItemDisplayWidth, scrollbarWidth,
|
||||
mDisplayFrame, mButtonFrame, mItemDisplayWidth, mCachedScrollbarWidth,
|
||||
borderPadding, size.height);
|
||||
|
||||
// The dropdown was reflowed UNCONSTRAINED before, now we need to check to see
|
||||
@@ -1534,17 +1545,21 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
// than for any particular item in the dropdown. So, if the new size of combobox
|
||||
// is smaller than the dropdown, that is OK, The dropdown MUST always be either the same
|
||||
//size as the combo or larger if necessary
|
||||
#if 1
|
||||
if (aDesiredSize.width > dropdownDesiredSize.width) {
|
||||
if (eReflowReason_Initial == firstPassState.reason) {
|
||||
firstPassState.reason = eReflowReason_Resize;
|
||||
}
|
||||
REFLOW_DEBUG_MSG3("*** Reflowing ListBox to width: %d it was %d\n", PX(aDesiredSize.width), PX(dropdownDesiredSize.width));
|
||||
|
||||
// Tell it we are doing the second pass, which means we will skip
|
||||
// doing the unconstained reflow, we already know that size
|
||||
nsListControlFrame * lcf = NS_STATIC_CAST(nsListControlFrame*, mDropdownFrame);
|
||||
lcf->SetPassId(2);
|
||||
// Reflow the dropdown list to match the width of the display + button
|
||||
ReflowComboChildFrame(mDropdownFrame, aPresContext, dropdownDesiredSize, firstPassState, aStatus,
|
||||
aDesiredSize.width, NS_UNCONSTRAINEDSIZE);
|
||||
lcf->SetPassId(0); // reset it back
|
||||
}
|
||||
#endif
|
||||
|
||||
#else // DO_NEW_REFLOW
|
||||
|
||||
@@ -1573,7 +1588,7 @@ nsComboboxControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
|
||||
// this reflows and makes and last minute adjustments
|
||||
ReflowCombobox(aPresContext, firstPassState, aDesiredSize, aStatus,
|
||||
mDisplayFrame, mButtonFrame, mItemDisplayWidth, scrollbarWidth,
|
||||
mDisplayFrame, mButtonFrame, mItemDisplayWidth, mCachedScrollbarWidth,
|
||||
borderPadding,
|
||||
aDesiredSize.height- borderPadding.top - borderPadding.bottom -
|
||||
dspBorderPadding.top - dspBorderPadding.bottom);
|
||||
|
||||
@@ -278,6 +278,7 @@ protected:
|
||||
// static class data member for Bug 32920
|
||||
// only one control can be focused at a time
|
||||
static nsComboboxControlFrame * mFocused;
|
||||
static nscoord mCachedScrollbarWidth;
|
||||
|
||||
#ifdef DO_REFLOW_COUNTER
|
||||
PRInt32 mReflowId;
|
||||
|
||||
@@ -242,6 +242,7 @@ nsListControlFrame::nsListControlFrame()
|
||||
mCachedUnconstrainedSize.height = -1;
|
||||
|
||||
mOverrideReflowOpt = PR_FALSE;
|
||||
mPassId = 0;
|
||||
|
||||
REFLOW_COUNTER_INIT()
|
||||
}
|
||||
@@ -611,62 +612,46 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
}
|
||||
}
|
||||
|
||||
nsresult res = nsScrollFrame::Reflow(aPresContext,
|
||||
scrolledAreaDesiredSize,
|
||||
firstPassState,
|
||||
aStatus);
|
||||
if (NS_FAILED(res)) {
|
||||
NS_ASSERTION(aDesiredSize.width < 100000, "Width is still NS_UNCONSTRAINEDSIZE");
|
||||
NS_ASSERTION(aDesiredSize.height < 100000, "Height is still NS_UNCONSTRAINEDSIZE");
|
||||
return res;
|
||||
if (mPassId == 0 || mPassId == 1) {
|
||||
nsresult res = nsScrollFrame::Reflow(aPresContext,
|
||||
scrolledAreaDesiredSize,
|
||||
firstPassState,
|
||||
aStatus);
|
||||
if (NS_FAILED(res)) {
|
||||
NS_ASSERTION(aDesiredSize.width < 100000, "Width is still NS_UNCONSTRAINEDSIZE");
|
||||
NS_ASSERTION(aDesiredSize.height < 100000, "Height is still NS_UNCONSTRAINEDSIZE");
|
||||
return res;
|
||||
}
|
||||
mCachedUnconstrainedSize.width = scrolledAreaDesiredSize.width;
|
||||
mCachedUnconstrainedSize.height = scrolledAreaDesiredSize.height;
|
||||
mCachedDesiredMaxSize.width = scrolledAreaDesiredSize.maxElementSize->width;
|
||||
mCachedDesiredMaxSize.height = scrolledAreaDesiredSize.maxElementSize->height;
|
||||
} else {
|
||||
scrolledAreaDesiredSize.width = mCachedUnconstrainedSize.width;
|
||||
scrolledAreaDesiredSize.height = mCachedUnconstrainedSize.height;
|
||||
scrolledAreaDesiredSize.maxElementSize->width = mCachedDesiredMaxSize.width;
|
||||
scrolledAreaDesiredSize.maxElementSize->height = mCachedDesiredMaxSize.height;
|
||||
}
|
||||
|
||||
nsIScrollableFrame * scrollableFrame = nsnull;
|
||||
nsRect scrolledRect;
|
||||
if (NS_SUCCEEDED(QueryInterface(NS_GET_IID(nsIScrollableFrame), (void**)&scrollableFrame))) {
|
||||
nsIFrame * scrolledFrame;
|
||||
scrollableFrame->GetScrolledFrame(aPresContext, scrolledFrame);
|
||||
NS_ASSERTION(scrolledFrame != nsnull, "Must have scrollable frame");
|
||||
scrolledFrame->GetRect(scrolledRect);
|
||||
} else {
|
||||
NS_ASSERTION(scrollableFrame != nsnull, "Must have scrollableFrame frame");
|
||||
}
|
||||
// Compute the bounding box of the contents of the list using the area
|
||||
// calculated by the first reflow as a starting point.
|
||||
//
|
||||
// The nsScrollFrame::REflow adds in the scrollbar width and border dimensions
|
||||
// to the maxElementSize, so these need to be subtracted
|
||||
nscoord scrolledAreaWidth = scrolledAreaDesiredSize.maxElementSize->width;
|
||||
nscoord scrolledAreaHeight = scrolledAreaDesiredSize.height;
|
||||
nscoord scrolledAreaWidth = scrolledAreaDesiredSize.maxElementSize->width -
|
||||
(aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right);
|
||||
nscoord scrolledAreaHeight = scrolledAreaDesiredSize.height -
|
||||
(aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom);
|
||||
|
||||
// Keep the oringal values
|
||||
// Set up max values
|
||||
mMaxWidth = scrolledAreaWidth;
|
||||
mMaxHeight = scrolledAreaDesiredSize.maxElementSize->height;
|
||||
|
||||
// The first reflow produces a box with the scrollbar width and borders
|
||||
// added in so we need to subtract them out.
|
||||
|
||||
// Retrieve the scrollbar's width and height
|
||||
float sbWidth = 0.0;
|
||||
float sbHeight = 0.0;;
|
||||
nsCOMPtr<nsIDeviceContext> dc;
|
||||
aPresContext->GetDeviceContext(getter_AddRefs(dc));
|
||||
dc->GetScrollBarDimensions(sbWidth, sbHeight);
|
||||
// Convert to nscoord's by rounding
|
||||
nscoord scrollbarWidth = NSToCoordRound(sbWidth);
|
||||
//nscoord scrollbarHeight = NSToCoordRound(sbHeight);
|
||||
|
||||
mMaxWidth -= aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right;
|
||||
mMaxHeight -= aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom;
|
||||
mMaxHeight = scrolledAreaDesiredSize.maxElementSize->height -
|
||||
(aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom);
|
||||
|
||||
// Now the scrolledAreaWidth and scrolledAreaHeight are exactly
|
||||
// wide and high enough to enclose their contents
|
||||
|
||||
PRBool isInDropDownMode = IsInDropDownMode();
|
||||
|
||||
scrolledAreaWidth -= aReflowState.mComputedBorderPadding.left + aReflowState.mComputedBorderPadding.right;
|
||||
scrolledAreaHeight -= aReflowState.mComputedBorderPadding.top + aReflowState.mComputedBorderPadding.bottom;
|
||||
|
||||
nscoord visibleWidth = 0;
|
||||
if (isInDropDownMode) {
|
||||
if (NS_UNCONSTRAINEDSIZE == aReflowState.mComputedWidth) {
|
||||
@@ -679,7 +664,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
if (NS_UNCONSTRAINEDSIZE == aReflowState.mComputedWidth) {
|
||||
visibleWidth = scrolledAreaWidth;
|
||||
} else {
|
||||
visibleWidth = aReflowState.mComputedWidth;// - scrollbarWidth;
|
||||
visibleWidth = aReflowState.mComputedWidth;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -870,9 +855,16 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
secondPassState.mComputedHeight = visibleHeight;
|
||||
secondPassState.reason = eReflowReason_Resize;
|
||||
|
||||
nsScrollFrame::Reflow(aPresContext, aDesiredSize, secondPassState, aStatus);
|
||||
|
||||
if (mPassId == 0 || mPassId == 2) {
|
||||
nsScrollFrame::Reflow(aPresContext, aDesiredSize, secondPassState, aStatus);
|
||||
// Set the max element size to be the same as the desired element size.
|
||||
} else {
|
||||
aDesiredSize.width = visibleWidth;
|
||||
aDesiredSize.height = visibleHeight;
|
||||
aDesiredSize.ascent = aDesiredSize.height;
|
||||
aDesiredSize.descent = 0;
|
||||
}
|
||||
|
||||
if (nsnull != aDesiredSize.maxElementSize) {
|
||||
aDesiredSize.maxElementSize->width = aDesiredSize.width;
|
||||
aDesiredSize.maxElementSize->height = aDesiredSize.height;
|
||||
@@ -880,7 +872,7 @@ nsListControlFrame::Reflow(nsIPresContext* aPresContext,
|
||||
|
||||
aStatus = NS_FRAME_COMPLETE;
|
||||
|
||||
#ifdef DEBUG_rods
|
||||
#ifdef DEBUG_rodsX
|
||||
if (!isInDropDownMode) {
|
||||
PRInt32 numRows = 1;
|
||||
GetSizeAttribute(&numRows);
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_rods
|
||||
#define DO_REFLOW_DEBUG
|
||||
#define DO_REFLOW_COUNTER
|
||||
//#define DO_REFLOW_DEBUG
|
||||
//#define DO_REFLOW_COUNTER
|
||||
//#define DO_UNCONSTRAINED_CHECK
|
||||
//#define DO_PIXELS
|
||||
#endif
|
||||
@@ -290,6 +290,9 @@ public:
|
||||
nsCWeakReferent *WeakReferent()
|
||||
{ return &mWeakReferent; }
|
||||
|
||||
// Helper
|
||||
void SetPassId(PRInt16 aId) { mPassId = aId; }
|
||||
|
||||
protected:
|
||||
|
||||
NS_IMETHOD GetSelectedIndexFromDOM(PRInt32* aIndex); // from DOM
|
||||
@@ -402,6 +405,9 @@ protected:
|
||||
// XXX temprary only until full system mouse capture works
|
||||
PRBool mIsScrollbarVisible;
|
||||
|
||||
PRInt16 mPassId;
|
||||
nsSize mCachedDesiredMaxSize;
|
||||
|
||||
//Resize Reflow OpitmizationSize;
|
||||
nsSize mCacheSize;
|
||||
nsSize mCachedMaxElementSize;
|
||||
|
||||
Reference in New Issue
Block a user