diff --git a/gfx/src/windows/nsFontMetricsWin.cpp b/gfx/src/windows/nsFontMetricsWin.cpp index 48a491621b67..7de77d43b37c 100644 --- a/gfx/src/windows/nsFontMetricsWin.cpp +++ b/gfx/src/windows/nsFontMetricsWin.cpp @@ -65,6 +65,9 @@ const char* nsFontMetricsWin::MapFamilyToFont(const nsString& aLogicalFontName) if (aLogicalFontName.EqualsIgnoreCase("Courier")) { return "Courier New"; } + if (aLogicalFontName.EqualsIgnoreCase("Courier New")) { + return "Courier New"; + } // the CSS generic names if (aLogicalFontName.EqualsIgnoreCase("serif")) { diff --git a/layout/html/forms/public/nsIFormManager.h b/layout/html/forms/public/nsIFormManager.h index a894f378fa98..14b3cf665853 100644 --- a/layout/html/forms/public/nsIFormManager.h +++ b/layout/html/forms/public/nsIFormManager.h @@ -22,12 +22,19 @@ class nsIFormControl; class nsIPresContext; class nsIFrame; +class nsString; // IID for the nsIFormManager interface #define NS_IFORMMANAGER_IID \ { 0x592daa01, 0xcb23, 0x11d1, \ { 0x80, 0x2d, 0x0, 0x60, 0x8, 0x15, 0xa7, 0x91 } } +// this is temporary until a more global solution is developed +enum nsFormRenderingMode { + kBackwardMode = 0, // nav 4 + kForwardMode // newest +}; + /** * Abstract form manager interface. Form managers are responsible for * the management of form controls. This includes gathering of data @@ -137,6 +144,9 @@ public: * @return the ref count */ virtual nsrefcnt GetRefCount() const = 0; + + virtual nsFormRenderingMode GetMode() const = 0; + virtual void SetMode(nsFormRenderingMode aMode) = 0; }; #endif /* nsIFormManager_h___ */ diff --git a/layout/html/forms/src/nsForm.cpp b/layout/html/forms/src/nsForm.cpp index 773579c66bbc..758682cf7767 100644 --- a/layout/html/forms/src/nsForm.cpp +++ b/layout/html/forms/src/nsForm.cpp @@ -143,9 +143,13 @@ public: virtual void Init(PRBool aReinit); + virtual nsFormRenderingMode GetMode() const { return mRenderingMode; } + virtual void SetMode(nsFormRenderingMode aMode) { mRenderingMode = aMode; } + static nsString* gGET; static nsString* gMULTIPART; + protected: void RemoveRadioGroups(); void ProcessAsURLEncoded(PRBool aIsPost, nsIFormControl* aSubmitter, nsString& aData); @@ -165,7 +169,8 @@ protected: nsString* mEncoding; nsString* mTarget; PRInt32 mMethod; - PRBool mInited; + PRBool mInited; + nsFormRenderingMode mRenderingMode; }; #define METHOD_UNSET 0 @@ -746,6 +751,10 @@ void nsForm::SetAttribute(const nsString& aName, const nsString& aValue) mMethod = METHOD_GET; } } + // temporarily, use type attribute to set the rendering mode + else if (atom == nsHTMLAtoms::type) { + mRenderingMode = (aValue.EqualsIgnoreCase("forward")) ? kForwardMode : kBackwardMode; + } else { // Use default storage for unknown attributes if (nsnull == mAttributes) { diff --git a/layout/html/forms/src/nsInputButton.cpp b/layout/html/forms/src/nsInputButton.cpp index 3bec9399de4a..46b80755b884 100644 --- a/layout/html/forms/src/nsInputButton.cpp +++ b/layout/html/forms/src/nsInputButton.cpp @@ -75,11 +75,11 @@ public: virtual void MapAttributesInto(nsIStyleContext* aContext, nsIPresContext* aPresContext); - virtual void GetDefaultLabel(nsString& aLabel); - nsButtonType GetButtonType() { return mType; } nsButtonTagType GetButtonTagType() { return mTagType; } + virtual void GetDefaultLabel(nsString& aLabel); + virtual PRInt32 GetMaxNumValues(); virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, @@ -123,6 +123,13 @@ public: nsButtonType GetButtonType() const; nsButtonTagType GetButtonTagType() const; + virtual PRInt32 GetVerticalBorderWidth(float aPixToTwip) const; + virtual PRInt32 GetHorizontalBorderWidth(float aPixToTwip) const; + virtual PRInt32 GetVerticalInsidePadding(float aPixToTwip, + PRInt32 aInnerHeight) const; + virtual PRInt32 GetHorizontalInsidePadding(float aPixToTwip, + PRInt32 aInnerWidth) const; + protected: virtual ~nsInputButtonFrame(); @@ -211,11 +218,11 @@ nsInputButton::GetDefaultLabel(nsString& aString) if (kButton_Reset == mType) { aString = "Reset"; } else if (kButton_Submit == mType) { - aString = "Submit"; + aString = "Submit Query"; } else if (kButton_Browse == mType) { aString = "Browse..."; } else { - aString = "noname"; + aString = " "; } } @@ -351,6 +358,34 @@ nsInputButtonFrame::GetButtonTagType() const return button->GetButtonTagType(); } +PRInt32 nsInputButtonFrame::GetVerticalBorderWidth(float aPixToTwip) const +{ + return (int)(4 * aPixToTwip + 0.5); +} + +PRInt32 nsInputButtonFrame::GetHorizontalBorderWidth(float aPixToTwip) const +{ + return GetVerticalBorderWidth(aPixToTwip); +} + +PRInt32 nsInputButtonFrame::GetVerticalInsidePadding(float aPixToTwip, + PRInt32 aInnerHeight) const +{ + //return (int)(4 * aPixToTwip + 0.5); + return (int)(aInnerHeight * .25 + 0.5); +} + +PRInt32 nsInputButtonFrame::GetHorizontalInsidePadding(float aPixToTwip, + PRInt32 aInnerWidth) const +{ + if (kBackwardMode == GetMode()) { + return (int)(aInnerWidth * .25 + 0.5); + } + else { + return (int)(10 * aPixToTwip + 0.5); + } +} + NS_METHOD nsInputButtonFrame::Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect) @@ -466,18 +501,21 @@ nsInputButtonFrame::GetDesiredSize(nsIPresContext* aPresContext, nsSize size; PRBool widthExplicit, heightExplicit; PRInt32 ignore; - nsInputDimensionSpec spec(nsHTMLAtoms::size, PR_TRUE, nsHTMLAtoms::value, 1, - PR_FALSE, nsnull, 1); + nsInputButton* button = (nsInputButton *)mContent; + nsAutoString defaultLabel; + button->GetDefaultLabel(defaultLabel); + nsInputDimensionSpec spec(nsHTMLAtoms::size, PR_TRUE, nsHTMLAtoms::value, + &defaultLabel, 1, PR_FALSE, nsnull, 1); CalculateSize(aPresContext, this, styleSize, spec, size, widthExplicit, heightExplicit, ignore); - +#if 0 if (!widthExplicit) { size.width += 100; } if (!heightExplicit) { size.height += 100; } - +#endif aDesiredLayoutSize.width = size.width; aDesiredLayoutSize.height= size.height; } diff --git a/layout/html/forms/src/nsInputCheckbox.cpp b/layout/html/forms/src/nsInputCheckbox.cpp index 62efbb0c5d03..05c6d349219d 100644 --- a/layout/html/forms/src/nsInputCheckbox.cpp +++ b/layout/html/forms/src/nsInputCheckbox.cpp @@ -47,7 +47,6 @@ public: protected: virtual ~nsInputCheckboxFrame(); - PRBool mCacheState; virtual void GetDesiredSize(nsIPresContext* aPresContext, const nsReflowState& aReflowState, nsReflowMetrics& aDesiredLayoutSize, @@ -61,7 +60,6 @@ nsInputCheckboxFrame::nsInputCheckboxFrame(nsIContent* aContent, nsIFrame* aPare nsInputCheckboxFrame::~nsInputCheckboxFrame() { - mCacheState = PR_FALSE; } NS_METHOD nsInputCheckboxFrame::SetRect(const nsRect& aRect) @@ -97,15 +95,6 @@ nsInputCheckboxFrame::GetDesiredSize(nsIPresContext* aPresContext, nsReflowMetrics& aDesiredLayoutSize, nsSize& aDesiredWidgetSize) { - nsInputCheckbox* content = (nsInputCheckbox *)mContent; // this must be an nsCheckbox - - // get the intial state - nsHTMLValue value; - nsContentAttr result = content->GetAttribute(nsHTMLAtoms::checked, value); - if (result != eContentAttr_NotThere) { - mCacheState = PR_TRUE;/* XXX why cache state? */ - } - float p2t = aPresContext->GetPixelsToTwips(); aDesiredWidgetSize.width = (int)(12 * p2t); aDesiredWidgetSize.height = (int)(12 * p2t); @@ -121,9 +110,16 @@ nsInputCheckboxFrame::GetDesiredSize(nsIPresContext* aPresContext, void nsInputCheckboxFrame::PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView) { + // get the intial state of the checkbox + nsInputCheckbox* content = (nsInputCheckbox *)mContent; // this must be an nsCheckbox + nsHTMLValue value; + nsContentAttr result = content->GetAttribute(nsHTMLAtoms::checked, value); + PRBool checked = (result != eContentAttr_NotThere) ? PR_TRUE : PR_FALSE; + + // set the widget to the initial state nsICheckButton* checkbox; if (NS_OK == GetWidget(aView, (nsIWidget **)&checkbox)) { - checkbox->SetState(mCacheState); + checkbox->SetState(checked); NS_RELEASE(checkbox); } } diff --git a/layout/html/forms/src/nsInputFrame.cpp b/layout/html/forms/src/nsInputFrame.cpp index 077311c6fba7..c12b9d7cf273 100644 --- a/layout/html/forms/src/nsInputFrame.cpp +++ b/layout/html/forms/src/nsInputFrame.cpp @@ -59,13 +59,50 @@ nsInputFrame::~nsInputFrame() { } -PRInt32 nsInputFrame::gScrollBarWidth = 360; - NS_METHOD nsInputFrame::SetRect(const nsRect& aRect) { return nsInputFrameSuper::SetRect(aRect); } +nsFormRenderingMode nsInputFrame::GetMode() const +{ + nsInput* content = (nsInput *)mContent; + nsIFormManager* formMan = content->GetFormManager(); + if (formMan) { + return formMan->GetMode(); + } + else { + return kBackwardMode; + } +} + +PRInt32 nsInputFrame::GetScrollbarWidth(float aPixToTwip) +{ + return (int)(16 * aPixToTwip + 0.5); +} + +PRInt32 nsInputFrame::GetVerticalBorderWidth(float aPixToTwip) const +{ + return (int)(3 * aPixToTwip + 0.5); +} + +PRInt32 nsInputFrame::GetHorizontalBorderWidth(float aPixToTwip) const +{ + return GetVerticalBorderWidth(aPixToTwip); +} + +PRInt32 nsInputFrame::GetVerticalInsidePadding(float aPixToTwip, + PRInt32 aInnerHeight) const +{ + return GetVerticalBorderWidth(aPixToTwip); +} + +PRInt32 nsInputFrame::GetHorizontalInsidePadding(float aPixToTwip, + PRInt32 aInnerWidth) const +{ + return GetVerticalInsidePadding(aPixToTwip, aInnerWidth); +} + NS_METHOD nsInputFrame::MoveTo(nscoord aX, nscoord aY) { @@ -110,10 +147,6 @@ nsInputFrame::SizeTo(nscoord aWidth, nscoord aHeight) return NS_OK; } -PRInt32 nsInputFrame::GetBorderSpacing(nsIPresContext& aPresContext) -{ - return (int)(2 * (aPresContext.GetPixelsToTwips() + .5)); -} // XXX it would be cool if form element used our rendering sw, then // they could be blended, and bordered, and so on... @@ -422,7 +455,7 @@ void nsInputFrame::GetStyleSize(nsIPresContext& aPresContext, } nscoord -nsInputFrame::GetTextSize(nsIPresContext& aPresContext, nsIFrame* aFrame, +nsInputFrame::GetTextSize(nsIPresContext& aPresContext, nsInputFrame* aFrame, const nsString& aString, nsSize& aSize) { //printf("\n GetTextSize %s", aString.ToNewCString()); @@ -435,9 +468,7 @@ nsInputFrame::GetTextSize(nsIPresContext& aPresContext, nsIFrame* aFrame, nsIFontMetrics* fontMet = fontCache->GetMetricsFor(styleFont->mFont); aSize.width = fontMet->GetWidth(aString); - aSize.height = fontMet->GetHeight() + fontMet->GetLeading(); - - aSize.height = (int)(((float)aSize.height) * .90); // XXX find out why this is necessary + aSize.height = fontMet->GetHeight(); nscoord charWidth = fontMet->GetWidth("W"); @@ -449,12 +480,13 @@ nsInputFrame::GetTextSize(nsIPresContext& aPresContext, nsIFrame* aFrame, } nscoord -nsInputFrame::GetTextSize(nsIPresContext& aPresContext, nsIFrame* aFrame, +nsInputFrame::GetTextSize(nsIPresContext& aPresContext, nsInputFrame* aFrame, PRInt32 aNumChars, nsSize& aSize) { nsAutoString val; + char repChar = (kBackwardMode == aFrame->GetMode()) ? '%' : 'e'; for (int i = 0; i < aNumChars; i++) { - val += 'e'; // use a typical char, what is the avg width character? + val += repChar; } return GetTextSize(aPresContext, aFrame, val, aSize); } @@ -487,10 +519,11 @@ nsInputFrame::CalculateSize (nsIPresContext* aPresContext, nsInputFrame* aFrame, if (nsnull != aSpec.mColSizeAttr) { colStatus = content->GetAttribute(aSpec.mColSizeAttr, colAttr); } + float p2t = aPresContext->GetPixelsToTwips(); + // determine the width if (eContentAttr_HasValue == colStatus) { // col attr will provide width if (aSpec.mColSizeAttrInPixels) { - float p2t = aPresContext->GetPixelsToTwips(); aBounds.width = (int) (((float)colAttr.GetPixelValue()) * p2t); } else { @@ -508,9 +541,12 @@ nsInputFrame::CalculateSize (nsIPresContext* aPresContext, nsInputFrame* aFrame, aWidthExplicit = PR_TRUE; } else { - if (eContentAttr_HasValue == valStatus) { // use width of initial value if specified + if (eContentAttr_HasValue == valStatus) { // use width of initial value charWidth = GetTextSize(*aPresContext, aFrame, valAttr, aBounds); } + else if (aSpec.mColDefaultValue) { // use default value + charWidth = GetTextSize(*aPresContext, aFrame, *aSpec.mColDefaultValue, aBounds); + } else if (aSpec.mColDefaultSizeInPixels) { // use default width in pixels charWidth = GetTextSize(*aPresContext, aFrame, 1, aBounds); aBounds.width = aSpec.mColDefaultSize; @@ -522,6 +558,7 @@ nsInputFrame::CalculateSize (nsIPresContext* aPresContext, nsInputFrame* aFrame, } } + // determine the height nsHTMLValue rowAttr; nsContentAttr rowStatus = eContentAttr_NotThere; if (nsnull != aSpec.mRowSizeAttr) { @@ -560,10 +597,12 @@ nsInputFrame::CalculateSize (nsIPresContext* aPresContext, nsInputFrame* aFrame, aRowHeight = textSize.height; } - // add padding to width if width wasn't specified either from css or - // size attr + // add inside padding if necessary if (!aWidthExplicit) { - aBounds.width += charWidth; + aBounds.width += (2 * aFrame->GetHorizontalInsidePadding(p2t, aBounds.width)); + } + if (!aHeightExplicit) { + aBounds.height += (2 * aFrame->GetVerticalInsidePadding(p2t, aBounds.height)); } NS_RELEASE(content); @@ -571,8 +610,6 @@ nsInputFrame::CalculateSize (nsIPresContext* aPresContext, nsInputFrame* aFrame, numRows = aBounds.height / aRowHeight; } - aBounds.height += (2 * aFrame->GetBorderSpacing(*aPresContext)); - return numRows; } diff --git a/layout/html/forms/src/nsInputFrame.h b/layout/html/forms/src/nsInputFrame.h index 3b5beaf34148..d1ef9c4daac9 100644 --- a/layout/html/forms/src/nsInputFrame.h +++ b/layout/html/forms/src/nsInputFrame.h @@ -19,6 +19,7 @@ #ifndef nsInputFrame_h___ #define nsInputFrame_h___ +#include "nsIFormManager.h" #include "nsHTMLContainer.h" #include "nsISupports.h" #include "nsIWidget.h" @@ -41,20 +42,23 @@ enum nsMouseState { struct nsInputDimensionSpec { - nsIAtom* mColSizeAttr; - PRBool mColSizeAttrInPixels; - nsIAtom* mColValueAttr; - nscoord mColDefaultSize; - PRBool mColDefaultSizeInPixels; - nsIAtom* mRowSizeAttr; - nscoord mRowDefaultSize; + nsIAtom* mColSizeAttr; // attribute used to determine width + PRBool mColSizeAttrInPixels; // is attribute value in pixels (otherwise num chars) + nsIAtom* mColValueAttr; // attribute used to get value to determine size + // if not determined above + nsString* mColDefaultValue; // default value if not determined above + nscoord mColDefaultSize; // default width if not determined above + PRBool mColDefaultSizeInPixels; // is default width in pixels (otherswise num chars) + nsIAtom* mRowSizeAttr; // attribute used to determine height + nscoord mRowDefaultSize; // default height if not determined above nsInputDimensionSpec(nsIAtom* aColSizeAttr, PRBool aColSizeAttrInPixels, - nsIAtom* aColValueAttr, nscoord aColDefaultSize, - PRBool aColDefaultSizeInPixels, + nsIAtom* aColValueAttr, nsString* aColDefaultValue, + nscoord aColDefaultSize, PRBool aColDefaultSizeInPixels, nsIAtom* aRowSizeAttr, nscoord aRowDefaultSize) : mColSizeAttr(aColSizeAttr), mColSizeAttrInPixels(aColSizeAttrInPixels), - mColValueAttr(aColValueAttr), mColDefaultSize(aColDefaultSize), + mColValueAttr(aColValueAttr), + mColDefaultValue(aColDefaultValue), mColDefaultSize(aColDefaultSize), mColDefaultSizeInPixels(aColDefaultSizeInPixels), mRowSizeAttr(aRowSizeAttr), mRowDefaultSize(aRowDefaultSize) { @@ -94,8 +98,6 @@ public: nsGUIEvent* aEvent, nsEventStatus& aEventStatus); - virtual PRInt32 GetBorderSpacing(nsIPresContext& aPresContext); - NS_IMETHOD SetRect(const nsRect& aRect); /** @@ -117,6 +119,7 @@ public: // new behavior + nsFormRenderingMode GetMode() const; /** * Return true if the underlying form element is a hidden form element */ @@ -161,16 +164,24 @@ public: */ virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext); - static nscoord GetTextSize(nsIPresContext& aContext, nsIFrame* aFrame, + static nscoord GetTextSize(nsIPresContext& aContext, nsInputFrame* aFrame, const nsString& aString, nsSize& aSize); - static nscoord GetTextSize(nsIPresContext& aContext, nsIFrame* aFrame, + static nscoord GetTextSize(nsIPresContext& aContext, nsInputFrame* aFrame, PRInt32 aNumChars, nsSize& aSize); - static PRInt32 gScrollBarWidth; - void GetWidgetSize(nsSize& aSize) const { aSize.width = mWidgetSize.width; aSize.height = mWidgetSize.height; } + // XXX similar functionality needs to be added to widget library and these + // need to change to use it. + static PRInt32 GetScrollbarWidth(float aPixToTwip); + virtual PRInt32 GetVerticalBorderWidth(float aPixToTwip) const; + virtual PRInt32 GetHorizontalBorderWidth(float aPixToTwip) const; + virtual PRInt32 GetVerticalInsidePadding(float aPixToTwip, + PRInt32 aInnerHeight) const; + virtual PRInt32 GetHorizontalInsidePadding(float aPixToTwip, + PRInt32 aInnerWidth) const; + protected: virtual ~nsInputFrame(); diff --git a/layout/html/forms/src/nsInputText.cpp b/layout/html/forms/src/nsInputText.cpp index 2291710872bd..b22305a6997a 100644 --- a/layout/html/forms/src/nsInputText.cpp +++ b/layout/html/forms/src/nsInputText.cpp @@ -47,6 +47,12 @@ public: virtual const nsIID& GetIID(); + virtual PRInt32 GetVerticalBorderWidth(float aPixToTwip) const; + virtual PRInt32 GetHorizontalBorderWidth(float aPixToTwip) const; + virtual PRInt32 GetVerticalInsidePadding(float aPixToTwip, + PRInt32 aInnerHeight) const; + virtual PRInt32 GetHorizontalInsidePadding(float aPixToTwip, + PRInt32 aInnerWidth) const; protected: virtual ~nsInputTextFrame(); @@ -69,6 +75,28 @@ nsInputTextFrame::~nsInputTextFrame() { } +PRInt32 nsInputTextFrame::GetVerticalBorderWidth(float aPixToTwip) const +{ + return (int)(4 * aPixToTwip + 0.5); +} + +PRInt32 nsInputTextFrame::GetHorizontalBorderWidth(float aPixToTwip) const +{ + return GetVerticalBorderWidth(aPixToTwip); +} + +PRInt32 nsInputTextFrame::GetVerticalInsidePadding(float aPixToTwip, + PRInt32 aInnerHeight) const +{ + return (int)(5 * aPixToTwip + 0.5); +} + +PRInt32 nsInputTextFrame::GetHorizontalInsidePadding(float aPixToTwip, + PRInt32 aInnerWidth) const +{ + return (int)(6 * aPixToTwip + 0.5); +} + const nsIID& nsInputTextFrame::GetIID() { @@ -125,28 +153,31 @@ nsInputTextFrame::GetDesiredSize(nsIPresContext* aPresContext, if ((kInputText_Text == textType) || (kInputText_Password == textType) || (kInputText_FileText == textType)) { - nsInputDimensionSpec textSpec(nsHTMLAtoms::size, PR_FALSE, nsHTMLAtoms::value, - 20, PR_FALSE, nsnull, 1); + nsInputDimensionSpec textSpec(nsHTMLAtoms::size, PR_FALSE, nsnull, + nsnull, 21, PR_FALSE, nsnull, 1); CalculateSize(aPresContext, this, styleSize, textSpec, size, widthExplicit, heightExplicit, ignore); } else { - nsInputDimensionSpec areaSpec(nsHTMLAtoms::cols, PR_FALSE, nsnull, 10, + nsInputDimensionSpec areaSpec(nsHTMLAtoms::cols, PR_FALSE, nsnull, nsnull, 20, PR_FALSE, nsHTMLAtoms::rows, 1); CalculateSize(aPresContext, this, styleSize, areaSpec, size, widthExplicit, heightExplicit, ignore); } + + float p2t = aPresContext->GetPixelsToTwips(); + PRInt32 scrollbarWidth = GetScrollbarWidth(p2t); if (!heightExplicit) { if (kInputText_Area == textType) { - size.height += gScrollBarWidth; + size.height += scrollbarWidth; + if (kBackwardMode == GetMode()) { + size.height += (int)(7 * p2t + 0.5); + } } - else { - size.height += 100; - } } if (!widthExplicit && (kInputText_Area == textType)) { - size.width += gScrollBarWidth; + size.width += scrollbarWidth; } aDesiredLayoutSize.width = size.width; diff --git a/layout/html/forms/src/nsSelect.cpp b/layout/html/forms/src/nsSelect.cpp index 159fd30dfb49..72d372fe1f47 100644 --- a/layout/html/forms/src/nsSelect.cpp +++ b/layout/html/forms/src/nsSelect.cpp @@ -56,6 +56,12 @@ public: virtual const nsIID& GetIID(); + virtual PRInt32 GetVerticalBorderWidth(float aPixToTwip) const; + virtual PRInt32 GetHorizontalBorderWidth(float aPixToTwip) const; + virtual PRInt32 GetVerticalInsidePadding(float aPixToTwip, + PRInt32 aInnerHeight) const; + virtual PRInt32 GetHorizontalInsidePadding(float aPixToTwip, + PRInt32 aInnerWidth) const; protected: virtual ~nsSelectFrame(); @@ -64,7 +70,6 @@ protected: const nsReflowState& aReflowState, nsReflowMetrics& aDesiredLayoutSize, nsSize& aDesiredWidgetSize); - PRBool mIsComboBox; }; class nsSelect : public nsInput @@ -94,6 +99,8 @@ public: virtual void Reset(); + PRBool mIsComboBox; + protected: virtual ~nsSelect(); @@ -140,7 +147,7 @@ protected: nsSelectFrame::nsSelectFrame(nsIContent* aContent, nsIFrame* aParentFrame) - : nsInputFrame(aContent, aParentFrame), mIsComboBox(PR_FALSE) + : nsInputFrame(aContent, aParentFrame) { } @@ -149,10 +156,33 @@ nsSelectFrame::~nsSelectFrame() } +PRInt32 nsSelectFrame::GetVerticalBorderWidth(float aPixToTwip) const +{ + return (int)(1 * aPixToTwip + 0.5); +} + +PRInt32 nsSelectFrame::GetHorizontalBorderWidth(float aPixToTwip) const +{ + return GetVerticalBorderWidth(aPixToTwip); +} + +PRInt32 nsSelectFrame::GetVerticalInsidePadding(float aPixToTwip, + PRInt32 aInnerHeight) const +{ + return (int)(1 * aPixToTwip + 0.5); +} + +PRInt32 nsSelectFrame::GetHorizontalInsidePadding(float aPixToTwip, + PRInt32 aInnerWidth) const +{ + return (int)(7 * aPixToTwip + 0.5); +} + const nsIID& nsSelectFrame::GetIID() { - if (mIsComboBox) { + nsSelect* content = (nsSelect *)mContent; + if (content->mIsComboBox) { return kComboBoxIID; } else { @@ -166,7 +196,8 @@ nsSelectFrame::GetCID() static NS_DEFINE_IID(kComboCID, NS_COMBOBOX_CID); static NS_DEFINE_IID(kListCID, NS_LISTBOX_CID); - if (mIsComboBox) { + nsSelect* content = (nsSelect *)mContent; + if (content->mIsComboBox) { return kComboCID; } else { @@ -208,30 +239,32 @@ nsSelectFrame::GetDesiredSize(nsIPresContext* aPresContext, PRInt32 rowHeight = 0; nsSize calcSize, charSize; PRBool widthExplicit, heightExplicit; - nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull, maxWidth, PR_TRUE, nsHTMLAtoms::size, 1); + nsInputDimensionSpec textSpec(nsnull, PR_FALSE, nsnull, nsnull, + maxWidth, PR_TRUE, nsHTMLAtoms::size, 1); PRInt32 numRows = CalculateSize(aPresContext, this, styleSize, textSpec, calcSize, widthExplicit, heightExplicit, rowHeight); // here it is determined whether we are a combo box PRInt32 sizeAttr = select->GetSize(); if (!select->GetMultiple() && ((1 == sizeAttr) || ((ATTR_NOTSET == sizeAttr) && (1 >= numRows)))) { - mIsComboBox = PR_TRUE; + select->mIsComboBox = PR_TRUE; } aDesiredLayoutSize.width = calcSize.width; // account for vertical scrollbar, if present - if (!widthExplicit && ((numRows < select->ChildCount()) || mIsComboBox)) { - aDesiredLayoutSize.width += gScrollBarWidth; + if (!widthExplicit && ((numRows < select->ChildCount()) || select->mIsComboBox)) { + float p2t = aPresContext->GetPixelsToTwips(); + aDesiredLayoutSize.width += GetScrollbarWidth(p2t); } // XXX put this in widget library, combo boxes are fixed height (visible part) - aDesiredLayoutSize.height = (mIsComboBox) ? 350 : calcSize.height; + aDesiredLayoutSize.height = (select->mIsComboBox) ? 350 : calcSize.height; aDesiredLayoutSize.ascent = aDesiredLayoutSize.height; aDesiredLayoutSize.descent = 0; aDesiredWidgetSize.width = aDesiredLayoutSize.width; aDesiredWidgetSize.height = aDesiredLayoutSize.height; - if (mIsComboBox) { // add in pull down size + if (select->mIsComboBox) { // add in pull down size aDesiredWidgetSize.height += (rowHeight * numChildren) + 100; } @@ -241,7 +274,8 @@ nsSelectFrame::GetDesiredSize(nsIPresContext* aPresContext, nsWidgetInitData* nsSelectFrame::GetWidgetInitData(nsIPresContext& aPresContext) { - if (mIsComboBox) { + nsSelect* select = (nsSelect *)mContent; + if (select->mIsComboBox) { nsComboBoxInitData* initData = new nsComboBoxInitData(); float twipToPix = aPresContext.GetTwipsToPixels(); initData->mDropDownHeight = NS_TO_INT_ROUND(mWidgetSize.height * twipToPix); @@ -297,7 +331,7 @@ nsSelectFrame::PostCreateWidget(nsIPresContext* aPresContext, nsIView *aView) // nsSelect nsSelect::nsSelect(nsIAtom* aTag, nsIFormManager* aFormMan) - : nsInput(aTag, aFormMan) + : nsInput(aTag, aFormMan), mIsComboBox(PR_FALSE) { mMultiple = PR_FALSE; } @@ -431,18 +465,25 @@ nsSelect::Reset() list->Deselect(); + PRInt32 selIndex = -1; for (int i = 0; i < numChildren; i++) { nsOption* option = (nsOption*)ChildAt(i); // YYY this had better be an option PRInt32 selAttr; ((nsInput *)option)->GetAttribute(nsHTMLAtoms::selected, selAttr); if (ATTR_NOTSET != selAttr) { list->SelectItem(i); + selIndex = i; if (!mMultiple) { break; } } NS_RELEASE(option); // YYY remove this comment if ok } + + // if none were selected, select 1st one if we are a combo box + if (mIsComboBox && (numChildren > 0) && (selIndex < 0)) { + list->SelectItem(0); + } }