From bd89429f516c87f6fb355641217bb6079c49b949 Mon Sep 17 00:00:00 2001 From: "rods%netscape.com" Date: Wed, 8 Sep 1999 14:27:38 +0000 Subject: [PATCH] Added the proper event processing for disabled options ListBoxes (as dropdowns) are now notified before the are about to be dropped down --- layout/forms/nsComboboxControlFrame.cpp | 3 +- layout/forms/nsIListControlFrame.h | 5 ++ layout/forms/nsListControlFrame.cpp | 68 ++++++++++++++++++- layout/forms/nsListControlFrame.h | 6 +- .../html/forms/public/nsIListControlFrame.h | 5 ++ .../html/forms/src/nsComboboxControlFrame.cpp | 3 +- layout/html/forms/src/nsListControlFrame.cpp | 68 ++++++++++++++++++- layout/html/forms/src/nsListControlFrame.h | 6 +- 8 files changed, 152 insertions(+), 12 deletions(-) diff --git a/layout/forms/nsComboboxControlFrame.cpp b/layout/forms/nsComboboxControlFrame.cpp index ef2f688a745a..0f57b329c71d 100644 --- a/layout/forms/nsComboboxControlFrame.cpp +++ b/layout/forms/nsComboboxControlFrame.cpp @@ -357,6 +357,7 @@ nsComboboxControlFrame::ShowList(nsIPresContext* aPresContext, PRBool aShowList) mDroppedDown = PR_TRUE; // The listcontrol frame will call back to the nsComboboxControlFrame's ListWasSelected // which will stop the capture. + mListControlFrame->AboutToDropDown(); mListControlFrame->CaptureMouseEvents(PR_TRUE); } else { ShowPopup(PR_FALSE); @@ -892,7 +893,7 @@ nsComboboxControlFrame::MouseDown(nsIDOMEvent* aMouseEvent) PositionDropdown(*mPresContext, displayRect.height, absoluteTwips, absolutePixels); ToggleList(mPresContext); - mIgnoreMouseUp = PR_TRUE; + //mIgnoreMouseUp = PR_TRUE; */ return NS_OK; } diff --git a/layout/forms/nsIListControlFrame.h b/layout/forms/nsIListControlFrame.h index 626d3968ce26..f347b85c9f70 100644 --- a/layout/forms/nsIListControlFrame.h +++ b/layout/forms/nsIListControlFrame.h @@ -81,6 +81,11 @@ public: */ NS_IMETHOD SyncViewWithFrame() = 0; + /** + * + */ + NS_IMETHOD AboutToDropDown() = 0; + }; #endif diff --git a/layout/forms/nsListControlFrame.cpp b/layout/forms/nsListControlFrame.cpp index 8337c1f4fa63..8c263ba46db2 100644 --- a/layout/forms/nsListControlFrame.cpp +++ b/layout/forms/nsListControlFrame.cpp @@ -201,6 +201,8 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext, //longest element in the list nsHTMLReflowState secondPassState(aReflowState); nsHTMLReflowState firstPassState(aReflowState); + //nsHTMLReflowState firstPassState(aPresContext, nsnull, + // this, aDesiredSize); // Get the size of option elements inside the listbox // Compute the width based on the longest line in the listbox. @@ -261,6 +263,12 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext, border.SizeTo(0, 0, 0, 0); } + nsMargin padding; + if (!aReflowState.mStyleSpacing->GetPadding(padding)) { + NS_NOTYETIMPLEMENTED("percentage padding"); + padding.SizeTo(0, 0, 0, 0); + } + mBorderOffsetY = border.top; scrolledAreaWidth -= (border.left + border.right); @@ -1122,6 +1130,7 @@ nsListControlFrame::IsContentSelected(nsIContent* aContent) { nsString value; nsIAtom * selectedAtom = NS_NewAtom(kMozSelected); + //nsIAtom * selectedAtom = NS_NewAtom("selected"); nsresult result = aContent->GetAttribute(kNameSpaceID_None, selectedAtom, value); NS_RELEASE(selectedAtom); @@ -1751,6 +1760,14 @@ nsListControlFrame::SyncViewWithFrame() return NS_OK; } +//--------------------------------------------------------- +NS_IMETHODIMP +nsListControlFrame::AboutToDropDown() +{ + mSelectedIndexWhenPoppedDown = mSelectedIndex; + return NS_OK; +} + //--------------------------------------------------------- nsresult nsListControlFrame::GetScrollingParentView(nsIFrame* aParent, nsIView** aParentView) @@ -1829,20 +1846,55 @@ nsListControlFrame::SetSuggestedSize(nscoord aWidth, nscoord aHeight) return NS_OK; } +//--------------------------------------------------------- +NS_IMETHODIMP +nsListControlFrame::IsTargetOptionDisabled(PRBool &aIsDisabled) +{ + nsresult rv = NS_ERROR_FAILURE; + aIsDisabled = PR_FALSE; + + nsIEventStateManager *stateManager; + rv = mPresContext->GetEventStateManager(&stateManager); + if (NS_OK == rv) { + nsIContent * content; + rv = stateManager->GetEventTargetContent(&content); + if (NS_OK == rv && nsnull != content) { + if (IsOptionElement(content)) { + aIsDisabled = nsFormFrame::GetDisabled(this, content); + } else { + rv = NS_ERROR_FAILURE; // return error when it is not an option + } + NS_RELEASE(content); + } + NS_RELEASE(stateManager); + } + return rv; +} + //---------------------------------------------------------------------- // nsIDOMMouseListener //---------------------------------------------------------------------- nsresult nsListControlFrame::MouseUp(nsIDOMEvent* aMouseEvent) { - //if (nsEventStatus_eConsumeNoDefault == aEventStatus) { - // return NS_OK; - //} if (nsFormFrame::GetDisabled(this)) { return NS_OK; } + // Check to see if the disabled option was clicked on + // NS_ERROR_FAILURE is returned is it isn't over an option + PRBool optionIsDisabled; + if (NS_OK == IsTargetOptionDisabled(optionIsDisabled)) { + if (optionIsDisabled) { + mSelectedIndex = mSelectedIndexWhenPoppedDown; + if (IsInDropDownMode() == PR_TRUE && mComboboxFrame) { + mComboboxFrame->ListWasSelected(mPresContext); + } + return NS_OK; + } + } + const nsStyleDisplay* disp = (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display); if (!disp->mVisible) { return NS_OK; @@ -1912,6 +1964,15 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent) if (nsFormFrame::GetDisabled(this)) { return NS_OK; } + + // Check to see if the disabled option was clicked on + // NS_ERROR_FAILURE is returned is it isn't over an option + PRBool optionIsDisabled; + if (NS_OK == IsTargetOptionDisabled(optionIsDisabled)) { + mSelectedIndex = mSelectedIndexWhenPoppedDown; + return NS_OK; + } + PRInt32 oldIndex; PRInt32 curIndex = mSelectedIndex; @@ -1927,6 +1988,7 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent) HandleListSelection(aMouseEvent); } } else { + // NOTE: the combo box is responsible for dropping it down if (mComboboxFrame) { PRBool isDroppedDown; mComboboxFrame->IsDroppedDown(&isDroppedDown); diff --git a/layout/forms/nsListControlFrame.h b/layout/forms/nsListControlFrame.h index 0a142b84c953..fccf099fe462 100644 --- a/layout/forms/nsListControlFrame.h +++ b/layout/forms/nsListControlFrame.h @@ -114,6 +114,7 @@ public: NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight); NS_IMETHOD GetNumberOfOptions(PRInt32* aNumOptions); NS_IMETHOD SyncViewWithFrame(); + NS_IMETHOD AboutToDropDown(); // nsISelectControlFrame NS_IMETHOD AddOption(PRInt32 index); @@ -147,7 +148,8 @@ public: protected: NS_IMETHOD GetSelectedIndexFromDOM(PRInt32* aIndex); // from DOM - + NS_IMETHOD IsTargetOptionDisabled(PRBool &aIsDisabled); + nsListControlFrame(); virtual ~nsListControlFrame(); @@ -191,12 +193,12 @@ protected: PRBool HasSameContent(nsIFrame* aFrame1, nsIFrame* aFrame2); void HandleListSelection(nsIDOMEvent * aDOMEvent); PRInt32 GetSelectedIndexFromFrame(nsIFrame *aHitFrame); - // Data Members nscoord mBorderOffsetY; nsFormFrame* mFormFrame; PRInt32 mSelectedIndex; PRInt32 mOldSelectedIndex; + PRInt32 mSelectedIndexWhenPoppedDown; PRInt32 mStartExtendedIndex; PRInt32 mEndExtendedIndex; nsIFrame* mHitFrame; diff --git a/layout/html/forms/public/nsIListControlFrame.h b/layout/html/forms/public/nsIListControlFrame.h index 626d3968ce26..f347b85c9f70 100644 --- a/layout/html/forms/public/nsIListControlFrame.h +++ b/layout/html/forms/public/nsIListControlFrame.h @@ -81,6 +81,11 @@ public: */ NS_IMETHOD SyncViewWithFrame() = 0; + /** + * + */ + NS_IMETHOD AboutToDropDown() = 0; + }; #endif diff --git a/layout/html/forms/src/nsComboboxControlFrame.cpp b/layout/html/forms/src/nsComboboxControlFrame.cpp index ef2f688a745a..0f57b329c71d 100644 --- a/layout/html/forms/src/nsComboboxControlFrame.cpp +++ b/layout/html/forms/src/nsComboboxControlFrame.cpp @@ -357,6 +357,7 @@ nsComboboxControlFrame::ShowList(nsIPresContext* aPresContext, PRBool aShowList) mDroppedDown = PR_TRUE; // The listcontrol frame will call back to the nsComboboxControlFrame's ListWasSelected // which will stop the capture. + mListControlFrame->AboutToDropDown(); mListControlFrame->CaptureMouseEvents(PR_TRUE); } else { ShowPopup(PR_FALSE); @@ -892,7 +893,7 @@ nsComboboxControlFrame::MouseDown(nsIDOMEvent* aMouseEvent) PositionDropdown(*mPresContext, displayRect.height, absoluteTwips, absolutePixels); ToggleList(mPresContext); - mIgnoreMouseUp = PR_TRUE; + //mIgnoreMouseUp = PR_TRUE; */ return NS_OK; } diff --git a/layout/html/forms/src/nsListControlFrame.cpp b/layout/html/forms/src/nsListControlFrame.cpp index 8337c1f4fa63..8c263ba46db2 100644 --- a/layout/html/forms/src/nsListControlFrame.cpp +++ b/layout/html/forms/src/nsListControlFrame.cpp @@ -201,6 +201,8 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext, //longest element in the list nsHTMLReflowState secondPassState(aReflowState); nsHTMLReflowState firstPassState(aReflowState); + //nsHTMLReflowState firstPassState(aPresContext, nsnull, + // this, aDesiredSize); // Get the size of option elements inside the listbox // Compute the width based on the longest line in the listbox. @@ -261,6 +263,12 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext, border.SizeTo(0, 0, 0, 0); } + nsMargin padding; + if (!aReflowState.mStyleSpacing->GetPadding(padding)) { + NS_NOTYETIMPLEMENTED("percentage padding"); + padding.SizeTo(0, 0, 0, 0); + } + mBorderOffsetY = border.top; scrolledAreaWidth -= (border.left + border.right); @@ -1122,6 +1130,7 @@ nsListControlFrame::IsContentSelected(nsIContent* aContent) { nsString value; nsIAtom * selectedAtom = NS_NewAtom(kMozSelected); + //nsIAtom * selectedAtom = NS_NewAtom("selected"); nsresult result = aContent->GetAttribute(kNameSpaceID_None, selectedAtom, value); NS_RELEASE(selectedAtom); @@ -1751,6 +1760,14 @@ nsListControlFrame::SyncViewWithFrame() return NS_OK; } +//--------------------------------------------------------- +NS_IMETHODIMP +nsListControlFrame::AboutToDropDown() +{ + mSelectedIndexWhenPoppedDown = mSelectedIndex; + return NS_OK; +} + //--------------------------------------------------------- nsresult nsListControlFrame::GetScrollingParentView(nsIFrame* aParent, nsIView** aParentView) @@ -1829,20 +1846,55 @@ nsListControlFrame::SetSuggestedSize(nscoord aWidth, nscoord aHeight) return NS_OK; } +//--------------------------------------------------------- +NS_IMETHODIMP +nsListControlFrame::IsTargetOptionDisabled(PRBool &aIsDisabled) +{ + nsresult rv = NS_ERROR_FAILURE; + aIsDisabled = PR_FALSE; + + nsIEventStateManager *stateManager; + rv = mPresContext->GetEventStateManager(&stateManager); + if (NS_OK == rv) { + nsIContent * content; + rv = stateManager->GetEventTargetContent(&content); + if (NS_OK == rv && nsnull != content) { + if (IsOptionElement(content)) { + aIsDisabled = nsFormFrame::GetDisabled(this, content); + } else { + rv = NS_ERROR_FAILURE; // return error when it is not an option + } + NS_RELEASE(content); + } + NS_RELEASE(stateManager); + } + return rv; +} + //---------------------------------------------------------------------- // nsIDOMMouseListener //---------------------------------------------------------------------- nsresult nsListControlFrame::MouseUp(nsIDOMEvent* aMouseEvent) { - //if (nsEventStatus_eConsumeNoDefault == aEventStatus) { - // return NS_OK; - //} if (nsFormFrame::GetDisabled(this)) { return NS_OK; } + // Check to see if the disabled option was clicked on + // NS_ERROR_FAILURE is returned is it isn't over an option + PRBool optionIsDisabled; + if (NS_OK == IsTargetOptionDisabled(optionIsDisabled)) { + if (optionIsDisabled) { + mSelectedIndex = mSelectedIndexWhenPoppedDown; + if (IsInDropDownMode() == PR_TRUE && mComboboxFrame) { + mComboboxFrame->ListWasSelected(mPresContext); + } + return NS_OK; + } + } + const nsStyleDisplay* disp = (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display); if (!disp->mVisible) { return NS_OK; @@ -1912,6 +1964,15 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent) if (nsFormFrame::GetDisabled(this)) { return NS_OK; } + + // Check to see if the disabled option was clicked on + // NS_ERROR_FAILURE is returned is it isn't over an option + PRBool optionIsDisabled; + if (NS_OK == IsTargetOptionDisabled(optionIsDisabled)) { + mSelectedIndex = mSelectedIndexWhenPoppedDown; + return NS_OK; + } + PRInt32 oldIndex; PRInt32 curIndex = mSelectedIndex; @@ -1927,6 +1988,7 @@ nsListControlFrame::MouseDown(nsIDOMEvent* aMouseEvent) HandleListSelection(aMouseEvent); } } else { + // NOTE: the combo box is responsible for dropping it down if (mComboboxFrame) { PRBool isDroppedDown; mComboboxFrame->IsDroppedDown(&isDroppedDown); diff --git a/layout/html/forms/src/nsListControlFrame.h b/layout/html/forms/src/nsListControlFrame.h index 0a142b84c953..fccf099fe462 100644 --- a/layout/html/forms/src/nsListControlFrame.h +++ b/layout/html/forms/src/nsListControlFrame.h @@ -114,6 +114,7 @@ public: NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight); NS_IMETHOD GetNumberOfOptions(PRInt32* aNumOptions); NS_IMETHOD SyncViewWithFrame(); + NS_IMETHOD AboutToDropDown(); // nsISelectControlFrame NS_IMETHOD AddOption(PRInt32 index); @@ -147,7 +148,8 @@ public: protected: NS_IMETHOD GetSelectedIndexFromDOM(PRInt32* aIndex); // from DOM - + NS_IMETHOD IsTargetOptionDisabled(PRBool &aIsDisabled); + nsListControlFrame(); virtual ~nsListControlFrame(); @@ -191,12 +193,12 @@ protected: PRBool HasSameContent(nsIFrame* aFrame1, nsIFrame* aFrame2); void HandleListSelection(nsIDOMEvent * aDOMEvent); PRInt32 GetSelectedIndexFromFrame(nsIFrame *aHitFrame); - // Data Members nscoord mBorderOffsetY; nsFormFrame* mFormFrame; PRInt32 mSelectedIndex; PRInt32 mOldSelectedIndex; + PRInt32 mSelectedIndexWhenPoppedDown; PRInt32 mStartExtendedIndex; PRInt32 mEndExtendedIndex; nsIFrame* mHitFrame;