generalized PostCreateWidget; better combo box rendering

This commit is contained in:
karnaze%netscape.com 1998-10-14 23:01:44 +00:00
parent eb971aca8b
commit 37f2d06fe4
16 changed files with 236 additions and 146 deletions

View File

@ -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)
{
}

View File

@ -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();

View File

@ -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)
{

View File

@ -270,7 +270,9 @@ nsTextControlFrame::GetText(nsString* aText)
}
void
nsTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext)
nsTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight)
{
if (!mWidget) {
return;

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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)
{
}

View File

@ -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();

View File

@ -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)
{

View File

@ -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))) {

View File

@ -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);

View File

@ -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");

View File

@ -270,7 +270,9 @@ nsTextControlFrame::GetText(nsString* aText)
}
void
nsTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext)
nsTextControlFrame::PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight)
{
if (!mWidget) {
return;

View File

@ -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();