From 4c91c0fff1fa172fff3950cfb83a907343adf1b9 Mon Sep 17 00:00:00 2001 From: "karnaze%netscape.com" Date: Wed, 14 Oct 1998 23:01:44 +0000 Subject: [PATCH] generalized PostCreateWidget; better combo box rendering --- layout/forms/nsFormControlFrame.cpp | 10 +- layout/forms/nsFormControlFrame.h | 3 +- layout/forms/nsHTMLButtonControlFrame.cpp | 136 ++++++++++-------- layout/forms/nsTextControlFrame.cpp | 4 +- layout/forms/nsTextControlFrame.h | 4 +- .../html/forms/src/nsButtonControlFrame.cpp | 2 +- layout/html/forms/src/nsButtonControlFrame.h | 4 +- .../html/forms/src/nsCheckboxControlFrame.cpp | 6 +- layout/html/forms/src/nsFormControlFrame.cpp | 10 +- layout/html/forms/src/nsFormControlFrame.h | 3 +- .../forms/src/nsHTMLButtonControlFrame.cpp | 136 ++++++++++-------- layout/html/forms/src/nsRadioControlFrame.cpp | 2 +- layout/html/forms/src/nsRadioControlFrame.h | 4 +- .../html/forms/src/nsSelectControlFrame.cpp | 50 ++++++- layout/html/forms/src/nsTextControlFrame.cpp | 4 +- layout/html/forms/src/nsTextControlFrame.h | 4 +- 16 files changed, 236 insertions(+), 146 deletions(-) diff --git a/layout/forms/nsFormControlFrame.cpp b/layout/forms/nsFormControlFrame.cpp index c23690bc49d..17ba8d64313 100644 --- a/layout/forms/nsFormControlFrame.cpp +++ b/layout/forms/nsFormControlFrame.cpp @@ -270,15 +270,19 @@ nsFormControlFrame::Reflow(nsIPresContext& aPresContext, formControl->SetWidget(mWidget); NS_RELEASE(formControl); } - PostCreateWidget(&aPresContext); + PostCreateWidget(&aPresContext, aDesiredSize.width, aDesiredSize.height); mDidInit = PR_TRUE; } else { NS_ASSERTION(0, "could not get widget"); } viewMan->InsertChild(parView, view, 0); - SetView(view); + + if ((aDesiredSize.width != boundBox.width) || (aDesiredSize.height != boundBox.height)) { + viewMan->ResizeView(view, aDesiredSize.width, aDesiredSize.height); + } + NS_IF_RELEASE(viewMan); } else { @@ -331,7 +335,7 @@ nsFormControlFrame::SetColors(nsIPresContext& aPresContext) } void -nsFormControlFrame::PostCreateWidget(nsIPresContext* aPresContext) +nsFormControlFrame::PostCreateWidget(nsIPresContext* aPresContext, nscoord& aWidth, nscoord& aHeight) { } diff --git a/layout/forms/nsFormControlFrame.h b/layout/forms/nsFormControlFrame.h index 4d70c38f61f..c808da66245 100644 --- a/layout/forms/nsFormControlFrame.h +++ b/layout/forms/nsFormControlFrame.h @@ -167,7 +167,8 @@ public: * Perform opertations after the widget associated with this frame has been * created. */ - virtual void PostCreateWidget(nsIPresContext* aPresContext); + virtual void PostCreateWidget(nsIPresContext* aPresContext, + nscoord& aWidth, nscoord& aHeight); void SetColors(nsIPresContext& aPresContext); virtual void Reset(); diff --git a/layout/forms/nsHTMLButtonControlFrame.cpp b/layout/forms/nsHTMLButtonControlFrame.cpp index 08c3238709a..bb7419270a9 100644 --- a/layout/forms/nsHTMLButtonControlFrame.cpp +++ b/layout/forms/nsHTMLButtonControlFrame.cpp @@ -102,7 +102,7 @@ protected: PRBool mInline; nsFormFrame* mFormFrame; nsMouseState mLastMouseState; - PRBool mGrabbingTheMouse; + nsCursor mPreviousCursor; }; nsresult @@ -123,7 +123,7 @@ nsHTMLButtonControlFrame::nsHTMLButtonControlFrame(nsIContent* aContent, { mInline = PR_TRUE; mLastMouseState = eMouseNone; - mGrabbingTheMouse = PR_FALSE; + mPreviousCursor = eCursor_standard; } nsHTMLButtonControlFrame::~nsHTMLButtonControlFrame() @@ -311,73 +311,87 @@ nsHTMLButtonControlFrame::HandleEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsEventStatus& aEventStatus) { - nsIWidget* window; - nsIView* view; - nsIViewManager* viewMan; - PRBool ignore; + static int foo = 0; - switch (aEvent->message) { - case NS_MOUSE_ENTER: // not implemented yet on frames - mLastMouseState = eMouseEnter; - break; - case NS_MOUSE_LEFT_BUTTON_DOWN: - mLastMouseState = eMouseDown; - //mLastMouseState = (eMouseEnter == mLastMouseState) ? eMouseDown : eMouseNone; - break; - case NS_MOUSE_MOVE: - GetWindow(window); - if (window) { - window->SetCursor(eCursor_arrow_west_plus); // XXX don't do this every time - NS_RELEASE(window); - } - if (!mGrabbingTheMouse) { - GetView(view); - if (view) { - view->GetViewManager(viewMan); - if (viewMan) { - viewMan->GrabMouseEvents(view, ignore); - NS_RELEASE(viewMan); - mGrabbingTheMouse = PR_TRUE; + aEventStatus = nsEventStatus_eIgnore; + nsresult result = NS_OK; + + nsIView* view; + GetView(view); + if (view) { + nsIViewManager* viewMan; + view->GetViewManager(viewMan); + if (viewMan) { + nsIView* grabber; + viewMan->GetMouseEventGrabber(grabber); + if ((grabber == view) || (nsnull == grabber)) { + nsIWidget* window; + PRBool ignore; + + switch (aEvent->message) { + case NS_MOUSE_ENTER: // not implemented yet on frames + mLastMouseState = eMouseEnter; + break; + case NS_MOUSE_LEFT_BUTTON_DOWN: + mLastMouseState = eMouseDown; + //mLastMouseState = (eMouseEnter == mLastMouseState) ? eMouseDown : eMouseNone; + break; + case NS_MOUSE_MOVE: +printf ("%d mRect=(%d,%d,%d,%d), x=%d, y=%d \n", foo, mRect.x, mRect.y, mRect.width, mRect.height, aEvent->point.x, aEvent->point.y); + if ((aEvent->point.x <= mRect.width) && (aEvent->point.y <= mRect.height)) { // mouse enter, frames don't support enter yet + if (nsnull == grabber) { +printf("%d enter\n", foo); + viewMan->GrabMouseEvents(view, ignore); + GetWindow(window); + if (window) { + mPreviousCursor = window->GetCursor(); + window->SetCursor(eCursor_standard); + //window->SetCursor(eCursor_sizeWE); //eCursor_arrow_west_plus); + NS_RELEASE(window); + } + } + } else { // mouse exit, frames don't support exit yet + viewMan->GrabMouseEvents(nsnull, ignore); +printf("%d exit\n", foo); + GetWindow(window); + if (window) { + window->SetCursor(mPreviousCursor); // eCursor_sizeWE + NS_RELEASE(window); + } } - } - } - break; - case NS_MOUSE_LEFT_BUTTON_UP: - if (eMouseDown == mLastMouseState) { - nsEventStatus status = nsEventStatus_eIgnore; - nsMouseEvent event; - event.eventStructType = NS_MOUSE_EVENT; - event.message = NS_MOUSE_LEFT_CLICK; - mContent->HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, status); + break; + case NS_MOUSE_LEFT_BUTTON_UP: + if (eMouseDown == mLastMouseState) { + nsEventStatus status = nsEventStatus_eIgnore; + nsMouseEvent event; + event.eventStructType = NS_MOUSE_EVENT; + event.message = NS_MOUSE_LEFT_CLICK; + mContent->HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, status); - if (nsEventStatus_eConsumeNoDefault != status) { - MouseClicked(&aPresContext); + if (nsEventStatus_eConsumeNoDefault != status) { + MouseClicked(&aPresContext); + } + } + mLastMouseState = eMouseEnter; + break; + case NS_MOUSE_EXIT: // doesn't work for frames, yet + break; } - } - mLastMouseState = eMouseEnter; - break; - case NS_MOUSE_EXIT: - GetWindow(window); - if (window) { - window->SetCursor(eCursor_standard); - NS_RELEASE(window); + aEventStatus = nsEventStatus_eConsumeNoDefault; + NS_RELEASE(viewMan); + return NS_OK; } - GetView(view); - if (view) { - view->GetViewManager(viewMan); - if (viewMan) { - viewMan->GrabMouseEvents(nsnull, ignore); - NS_RELEASE(viewMan); - mGrabbingTheMouse = PR_FALSE; - } - } - mLastMouseState = eMouseNone; - break; + } + } + if (nsnull == mFirstChild) { // XXX see corresponding hack in nsHTMLContainerFrame::DeleteFrame + aEventStatus = nsEventStatus_eConsumeNoDefault; + return NS_OK; + } else { + return nsHTMLContainerFrame::HandleEvent(aPresContext, aEvent, aEventStatus); } - aEventStatus = nsEventStatus_eConsumeNoDefault; - return NS_OK; } + NS_IMETHODIMP nsHTMLButtonControlFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) { diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp index 4312a2d7cb5..777a7c0df6b 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -270,7 +270,9 @@ nsTextControlFrame::GetText(nsString* aText) } void -nsTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext) +nsTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext, + nscoord& aWidth, + nscoord& aHeight) { if (!mWidget) { return; diff --git a/layout/forms/nsTextControlFrame.h b/layout/forms/nsTextControlFrame.h index 31910e35fc7..d163aff6814 100644 --- a/layout/forms/nsTextControlFrame.h +++ b/layout/forms/nsTextControlFrame.h @@ -30,7 +30,9 @@ public: virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext); - virtual void PostCreateWidget(nsIPresContext* aPresContext); + virtual void PostCreateWidget(nsIPresContext* aPresContext, + nscoord& aWidth, + nscoord& aHeight); virtual const nsIID& GetCID(); diff --git a/layout/html/forms/src/nsButtonControlFrame.cpp b/layout/html/forms/src/nsButtonControlFrame.cpp index cf4468ce0ca..fc662e8f7f7 100644 --- a/layout/html/forms/src/nsButtonControlFrame.cpp +++ b/layout/html/forms/src/nsButtonControlFrame.cpp @@ -350,7 +350,7 @@ nsButtonControlFrame::GetDesiredSize(nsIPresContext* aPresContext, void -nsButtonControlFrame::PostCreateWidget(nsIPresContext* aPresContext) +nsButtonControlFrame::PostCreateWidget(nsIPresContext* aPresContext, nscoord& aWidth, nscoord& aHeight) { PRInt32 type; GetType(&type); diff --git a/layout/html/forms/src/nsButtonControlFrame.h b/layout/html/forms/src/nsButtonControlFrame.h index 20f5a193024..588a261f995 100644 --- a/layout/html/forms/src/nsButtonControlFrame.h +++ b/layout/html/forms/src/nsButtonControlFrame.h @@ -36,7 +36,9 @@ public: const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus); - virtual void PostCreateWidget(nsIPresContext* aPresContext); + virtual void PostCreateWidget(nsIPresContext* aPresContext, + nscoord& aWidth, + nscoord& aHeight); virtual void MouseClicked(nsIPresContext* aPresContext); diff --git a/layout/html/forms/src/nsCheckboxControlFrame.cpp b/layout/html/forms/src/nsCheckboxControlFrame.cpp index 06fe8704694..98b568c172a 100644 --- a/layout/html/forms/src/nsCheckboxControlFrame.cpp +++ b/layout/html/forms/src/nsCheckboxControlFrame.cpp @@ -40,7 +40,9 @@ class nsCheckboxControlFrame : public nsFormControlFrame { public: nsCheckboxControlFrame(nsIContent* aContent, nsIFrame* aParentFrame); - virtual void PostCreateWidget(nsIPresContext* aPresContext); + virtual void PostCreateWidget(nsIPresContext* aPresContext, + nscoord& aWidth, + nscoord& aHeight); virtual const nsIID& GetCID(); @@ -142,7 +144,7 @@ nsCheckboxControlFrame::GetChecked(PRBool* aResult) } void -nsCheckboxControlFrame::PostCreateWidget(nsIPresContext* aPresContext) +nsCheckboxControlFrame::PostCreateWidget(nsIPresContext* aPresContext, nscoord& aWidth, nscoord& aHeight) { if (!mWidget) { return; diff --git a/layout/html/forms/src/nsFormControlFrame.cpp b/layout/html/forms/src/nsFormControlFrame.cpp index c23690bc49d..17ba8d64313 100644 --- a/layout/html/forms/src/nsFormControlFrame.cpp +++ b/layout/html/forms/src/nsFormControlFrame.cpp @@ -270,15 +270,19 @@ nsFormControlFrame::Reflow(nsIPresContext& aPresContext, formControl->SetWidget(mWidget); NS_RELEASE(formControl); } - PostCreateWidget(&aPresContext); + PostCreateWidget(&aPresContext, aDesiredSize.width, aDesiredSize.height); mDidInit = PR_TRUE; } else { NS_ASSERTION(0, "could not get widget"); } viewMan->InsertChild(parView, view, 0); - SetView(view); + + if ((aDesiredSize.width != boundBox.width) || (aDesiredSize.height != boundBox.height)) { + viewMan->ResizeView(view, aDesiredSize.width, aDesiredSize.height); + } + NS_IF_RELEASE(viewMan); } else { @@ -331,7 +335,7 @@ nsFormControlFrame::SetColors(nsIPresContext& aPresContext) } void -nsFormControlFrame::PostCreateWidget(nsIPresContext* aPresContext) +nsFormControlFrame::PostCreateWidget(nsIPresContext* aPresContext, nscoord& aWidth, nscoord& aHeight) { } diff --git a/layout/html/forms/src/nsFormControlFrame.h b/layout/html/forms/src/nsFormControlFrame.h index 4d70c38f61f..c808da66245 100644 --- a/layout/html/forms/src/nsFormControlFrame.h +++ b/layout/html/forms/src/nsFormControlFrame.h @@ -167,7 +167,8 @@ public: * Perform opertations after the widget associated with this frame has been * created. */ - virtual void PostCreateWidget(nsIPresContext* aPresContext); + virtual void PostCreateWidget(nsIPresContext* aPresContext, + nscoord& aWidth, nscoord& aHeight); void SetColors(nsIPresContext& aPresContext); virtual void Reset(); diff --git a/layout/html/forms/src/nsHTMLButtonControlFrame.cpp b/layout/html/forms/src/nsHTMLButtonControlFrame.cpp index 08c3238709a..bb7419270a9 100644 --- a/layout/html/forms/src/nsHTMLButtonControlFrame.cpp +++ b/layout/html/forms/src/nsHTMLButtonControlFrame.cpp @@ -102,7 +102,7 @@ protected: PRBool mInline; nsFormFrame* mFormFrame; nsMouseState mLastMouseState; - PRBool mGrabbingTheMouse; + nsCursor mPreviousCursor; }; nsresult @@ -123,7 +123,7 @@ nsHTMLButtonControlFrame::nsHTMLButtonControlFrame(nsIContent* aContent, { mInline = PR_TRUE; mLastMouseState = eMouseNone; - mGrabbingTheMouse = PR_FALSE; + mPreviousCursor = eCursor_standard; } nsHTMLButtonControlFrame::~nsHTMLButtonControlFrame() @@ -311,73 +311,87 @@ nsHTMLButtonControlFrame::HandleEvent(nsIPresContext& aPresContext, nsGUIEvent* aEvent, nsEventStatus& aEventStatus) { - nsIWidget* window; - nsIView* view; - nsIViewManager* viewMan; - PRBool ignore; + static int foo = 0; - switch (aEvent->message) { - case NS_MOUSE_ENTER: // not implemented yet on frames - mLastMouseState = eMouseEnter; - break; - case NS_MOUSE_LEFT_BUTTON_DOWN: - mLastMouseState = eMouseDown; - //mLastMouseState = (eMouseEnter == mLastMouseState) ? eMouseDown : eMouseNone; - break; - case NS_MOUSE_MOVE: - GetWindow(window); - if (window) { - window->SetCursor(eCursor_arrow_west_plus); // XXX don't do this every time - NS_RELEASE(window); - } - if (!mGrabbingTheMouse) { - GetView(view); - if (view) { - view->GetViewManager(viewMan); - if (viewMan) { - viewMan->GrabMouseEvents(view, ignore); - NS_RELEASE(viewMan); - mGrabbingTheMouse = PR_TRUE; + aEventStatus = nsEventStatus_eIgnore; + nsresult result = NS_OK; + + nsIView* view; + GetView(view); + if (view) { + nsIViewManager* viewMan; + view->GetViewManager(viewMan); + if (viewMan) { + nsIView* grabber; + viewMan->GetMouseEventGrabber(grabber); + if ((grabber == view) || (nsnull == grabber)) { + nsIWidget* window; + PRBool ignore; + + switch (aEvent->message) { + case NS_MOUSE_ENTER: // not implemented yet on frames + mLastMouseState = eMouseEnter; + break; + case NS_MOUSE_LEFT_BUTTON_DOWN: + mLastMouseState = eMouseDown; + //mLastMouseState = (eMouseEnter == mLastMouseState) ? eMouseDown : eMouseNone; + break; + case NS_MOUSE_MOVE: +printf ("%d mRect=(%d,%d,%d,%d), x=%d, y=%d \n", foo, mRect.x, mRect.y, mRect.width, mRect.height, aEvent->point.x, aEvent->point.y); + if ((aEvent->point.x <= mRect.width) && (aEvent->point.y <= mRect.height)) { // mouse enter, frames don't support enter yet + if (nsnull == grabber) { +printf("%d enter\n", foo); + viewMan->GrabMouseEvents(view, ignore); + GetWindow(window); + if (window) { + mPreviousCursor = window->GetCursor(); + window->SetCursor(eCursor_standard); + //window->SetCursor(eCursor_sizeWE); //eCursor_arrow_west_plus); + NS_RELEASE(window); + } + } + } else { // mouse exit, frames don't support exit yet + viewMan->GrabMouseEvents(nsnull, ignore); +printf("%d exit\n", foo); + GetWindow(window); + if (window) { + window->SetCursor(mPreviousCursor); // eCursor_sizeWE + NS_RELEASE(window); + } } - } - } - break; - case NS_MOUSE_LEFT_BUTTON_UP: - if (eMouseDown == mLastMouseState) { - nsEventStatus status = nsEventStatus_eIgnore; - nsMouseEvent event; - event.eventStructType = NS_MOUSE_EVENT; - event.message = NS_MOUSE_LEFT_CLICK; - mContent->HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, status); + break; + case NS_MOUSE_LEFT_BUTTON_UP: + if (eMouseDown == mLastMouseState) { + nsEventStatus status = nsEventStatus_eIgnore; + nsMouseEvent event; + event.eventStructType = NS_MOUSE_EVENT; + event.message = NS_MOUSE_LEFT_CLICK; + mContent->HandleDOMEvent(aPresContext, &event, nsnull, DOM_EVENT_INIT, status); - if (nsEventStatus_eConsumeNoDefault != status) { - MouseClicked(&aPresContext); + if (nsEventStatus_eConsumeNoDefault != status) { + MouseClicked(&aPresContext); + } + } + mLastMouseState = eMouseEnter; + break; + case NS_MOUSE_EXIT: // doesn't work for frames, yet + break; } - } - mLastMouseState = eMouseEnter; - break; - case NS_MOUSE_EXIT: - GetWindow(window); - if (window) { - window->SetCursor(eCursor_standard); - NS_RELEASE(window); + aEventStatus = nsEventStatus_eConsumeNoDefault; + NS_RELEASE(viewMan); + return NS_OK; } - GetView(view); - if (view) { - view->GetViewManager(viewMan); - if (viewMan) { - viewMan->GrabMouseEvents(nsnull, ignore); - NS_RELEASE(viewMan); - mGrabbingTheMouse = PR_FALSE; - } - } - mLastMouseState = eMouseNone; - break; + } + } + if (nsnull == mFirstChild) { // XXX see corresponding hack in nsHTMLContainerFrame::DeleteFrame + aEventStatus = nsEventStatus_eConsumeNoDefault; + return NS_OK; + } else { + return nsHTMLContainerFrame::HandleEvent(aPresContext, aEvent, aEventStatus); } - aEventStatus = nsEventStatus_eConsumeNoDefault; - return NS_OK; } + NS_IMETHODIMP nsHTMLButtonControlFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList) { diff --git a/layout/html/forms/src/nsRadioControlFrame.cpp b/layout/html/forms/src/nsRadioControlFrame.cpp index fad3dd31716..a17656e4673 100644 --- a/layout/html/forms/src/nsRadioControlFrame.cpp +++ b/layout/html/forms/src/nsRadioControlFrame.cpp @@ -97,7 +97,7 @@ nsRadioControlFrame::GetDesiredSize(nsIPresContext* aPresContext, } void -nsRadioControlFrame::PostCreateWidget(nsIPresContext* aPresContext) +nsRadioControlFrame::PostCreateWidget(nsIPresContext* aPresContext, nscoord& aWidth, nscoord& aHeight) { nsIRadioButton* radio = nsnull; if (mWidget && (NS_OK == mWidget->QueryInterface(GetIID(),(void**)&radio))) { diff --git a/layout/html/forms/src/nsRadioControlFrame.h b/layout/html/forms/src/nsRadioControlFrame.h index fce333baf70..db6d35d27b0 100644 --- a/layout/html/forms/src/nsRadioControlFrame.h +++ b/layout/html/forms/src/nsRadioControlFrame.h @@ -31,7 +31,9 @@ class nsRadioControlFrame : public nsFormControlFrame public: nsRadioControlFrame(nsIContent* aContent, nsIFrame* aParentFrame); - virtual void PostCreateWidget(nsIPresContext* aPresContext); + virtual void PostCreateWidget(nsIPresContext* aPresContext, + nscoord& aWidth, + nscoord& aHeight); virtual PRBool GetChecked(PRBool aGetInitialValue); virtual void SetChecked(PRBool aValue, PRBool aSetInitialValue); diff --git a/layout/html/forms/src/nsSelectControlFrame.cpp b/layout/html/forms/src/nsSelectControlFrame.cpp index 3103192e534..a820cdc2304 100644 --- a/layout/html/forms/src/nsSelectControlFrame.cpp +++ b/layout/html/forms/src/nsSelectControlFrame.cpp @@ -64,7 +64,9 @@ public: virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext); - virtual void PostCreateWidget(nsIPresContext* aPresContext); + virtual void PostCreateWidget(nsIPresContext* aPresContext, + nscoord& aWidth, + nscoord& aHeight); virtual const nsIID& GetCID(); @@ -99,6 +101,8 @@ protected: nsHTMLReflowMetrics& aDesiredLayoutSize, nsSize& aDesiredWidgetSize); + void GetWidgetSize(nsIPresContext& aPresContext, nscoord& aWidth, nscoord& aHeight); + PRBool mIsComboBox; PRBool mOptionsAdded; }; @@ -145,7 +149,7 @@ nsSelectControlFrame::GetVerticalInsidePadding(float aPixToTwip, nscoord aInnerHeight) const { #ifdef XP_PC - return (nscoord)NSToIntRound(float(aInnerHeight) * 0.15f); + return (nscoord)NSToIntRound(float(aInnerHeight) * 0.10f); #endif #ifdef XP_UNIX return NSIntPixelsToTwips(1, aPixToTwip); // XXX this is probably wrong @@ -206,6 +210,7 @@ nsSelectControlFrame::GetDesiredSize(nsIPresContext* aPresContext, if (!options) { return; } + // get the css size nsSize styleSize; GetStyleSize(*aPresContext, aReflowState, styleSize); @@ -250,23 +255,34 @@ nsSelectControlFrame::GetDesiredSize(nsIPresContext* aPresContext, ((1 >= sizeAttr) || ((ATTR_NOTSET == sizeAttr) && (1 >= numRows)))) { mIsComboBox = PR_TRUE; } + + float p2t = aPresContext->GetPixelsToTwips(); aDesiredLayoutSize.width = calcSize.width; // account for vertical scrollbar, if present if (!widthExplicit && ((numRows < numOptions) || 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 = (mIsComboBox) + ? rowHeight + (2 * GetVerticalInsidePadding(p2t, rowHeight)) + : calcSize.height; aDesiredLayoutSize.ascent = aDesiredLayoutSize.height; aDesiredLayoutSize.descent = 0; aDesiredWidgetSize.width = aDesiredLayoutSize.width; aDesiredWidgetSize.height = aDesiredLayoutSize.height; if (mIsComboBox) { // add in pull down size - aDesiredWidgetSize.height += (rowHeight * (numOptions > 20 ? 20 : numOptions)) + 100; + PRInt32 extra = NSIntPixelsToTwips(10, p2t); + aDesiredWidgetSize.height += (rowHeight * (numOptions > 20 ? 20 : numOptions)) + extra; + } + + // override the width and height for a combo box that has already got a widget + if (mWidget && mIsComboBox) { + nscoord ignore; + GetWidgetSize(*aPresContext, ignore, aDesiredLayoutSize.height); + aDesiredLayoutSize.ascent = aDesiredLayoutSize.height; } NS_RELEASE(options); @@ -341,13 +357,35 @@ nsSelectControlFrame::GetOptions(nsIDOMHTMLSelectElement* aSelect) } } +void +nsSelectControlFrame::GetWidgetSize(nsIPresContext& aPresContext, nscoord& aWidth, nscoord& aHeight) +{ + nsRect bounds; + mWidget->GetBounds(bounds); + float p2t = aPresContext.GetPixelsToTwips(); + aWidth = NSIntPixelsToTwips(bounds.width, p2t); + aHeight = NSTwipsToIntPixels(bounds.height, p2t); +} + void -nsSelectControlFrame::PostCreateWidget(nsIPresContext* aPresContext) +nsSelectControlFrame::PostCreateWidget(nsIPresContext* aPresContext, + nscoord& aWidth, + nscoord& aHeight) { if (!mWidget) { return; } + // get the size of the combo box and let Reflow change its desired size + if (mIsComboBox) { // hack + nscoord ignore; + nscoord height; + GetWidgetSize(*aPresContext, ignore, height); + if (height > aHeight) { + aHeight = height; + } + } + nsIListWidget* listWidget; if (NS_OK != mWidget->QueryInterface(kListWidgetIID, (void **) &listWidget)) { NS_ASSERTION(PR_FALSE, "invalid widget"); diff --git a/layout/html/forms/src/nsTextControlFrame.cpp b/layout/html/forms/src/nsTextControlFrame.cpp index 4312a2d7cb5..777a7c0df6b 100644 --- a/layout/html/forms/src/nsTextControlFrame.cpp +++ b/layout/html/forms/src/nsTextControlFrame.cpp @@ -270,7 +270,9 @@ nsTextControlFrame::GetText(nsString* aText) } void -nsTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext) +nsTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext, + nscoord& aWidth, + nscoord& aHeight) { if (!mWidget) { return; diff --git a/layout/html/forms/src/nsTextControlFrame.h b/layout/html/forms/src/nsTextControlFrame.h index 31910e35fc7..d163aff6814 100644 --- a/layout/html/forms/src/nsTextControlFrame.h +++ b/layout/html/forms/src/nsTextControlFrame.h @@ -30,7 +30,9 @@ public: virtual nsWidgetInitData* GetWidgetInitData(nsIPresContext& aPresContext); - virtual void PostCreateWidget(nsIPresContext* aPresContext); + virtual void PostCreateWidget(nsIPresContext* aPresContext, + nscoord& aWidth, + nscoord& aHeight); virtual const nsIID& GetCID();