When clicking away from the dropdown, it wasn't resetting itself correctly.

If only the mouse was being used for selection, then it needs to reset itself to the state before dropping down
if arrow keys had been used then it needs to keep that selection
The combobox chaches the current selection, so when arrow keys are used it has the correct selection
when the mouse is used it holds the old selection. So therefore, we can compare against it
to determine what to do.
Bug 63247
r=waqar sr=hyatt
This commit is contained in:
rods%netscape.com 2000-12-20 23:25:40 +00:00
parent b2b9ae0910
commit 706bdfa5fd
8 changed files with 98 additions and 8 deletions

View File

@ -1939,6 +1939,13 @@ nsComboboxControlFrame::SelectionChanged()
return rv;
}
NS_IMETHODIMP
nsComboboxControlFrame::GetIndexOfDisplayArea(PRInt32* aSelectedIndex)
{
NS_ENSURE_ARG_POINTER(aSelectedIndex);
*aSelectedIndex = mSelectedIndex;
return NS_OK;
}
//----------------------------------------------------------------------
// nsISelectControlFrame

View File

@ -166,6 +166,7 @@ public:
NS_IMETHOD UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, PRInt32 aNewIndex);
NS_IMETHOD AbsolutelyPositionDropDown();
NS_IMETHOD GetAbsoluteRect(nsRect* aRect);
NS_IMETHOD GetIndexOfDisplayArea(PRInt32* aSelectedIndex);
// nsISelectControlFrame
NS_IMETHOD AddOption(nsIPresContext* aPresContext, PRInt32 index);

View File

@ -115,6 +115,23 @@ public:
*/
NS_IMETHOD SetFrameConstructor(nsCSSFrameConstructor *aConstructor) = 0;
/**
* This returns the index of the item that is currently being displayed
* in the display area. It may differ from what the currently Selected index
* is in in the dropdown.
*
* Detailed explanation:
* When the dropdown is dropped down via a mouse click and the user moves the mouse
* up and down without clicking, the currently selected item is being tracking inside
* the dropdown, but the combobox is not being updated. When the user selects items
* with the arrow keys, the combobox is being updated. So when the user clicks outside
* the dropdown and it needs to roll up it has to decide whether to keep the current
* selection or not. This method is used to get the current index in the combobox to
* compare it to the current index in the dropdown to see if the combox has been updated
* and that way it knows whether to "cancel" the the current selection residing in the
* dropdown. Or whether to leave the selection alone.
*/
NS_IMETHOD GetIndexOfDisplayArea(PRInt32* aSelectedIndex) = 0;
};
#endif

View File

@ -2847,10 +2847,30 @@ nsListControlFrame::AboutToDropDown()
NS_IMETHODIMP
nsListControlFrame::AboutToRollup()
{
// XXX By uncommenting this line below the "act" of rolling up
// will reset the the contents of the combobox to it's original contents
// (i.e. the contents before it was dropped down
ResetSelectedItem();
// XXX To have clicking outside the combobox ALWAYS reset the contents to the
// state before it was dropped, remove the all the code in the "if" below and replace it
// with just the call to ResetSelectedItem()
//
//
// When the dropdown is dropped down via a mouse click and the user moves the mouse
// up and down without clicking, the currently selected item is being tracking inside
// the dropdown, but the combobox is not being updated. When the user selects items
// with the arrow keys, the combobox is being updated. So when the user clicks outside
// the dropdown and it needs to roll up it has to decide whether to keep the current
// selection or not. The GetIndexOfDisplayArea method is used to get the current index
// in the combobox to compare it to the current index in the dropdown to see if the combox
// has been updated and that way it knows whether to "cancel" the the current selection
// residing in the dropdown. Or whether to leave the selection alone.
if (IsInDropDownMode() == PR_TRUE) {
PRInt32 index;
mComboboxFrame->GetIndexOfDisplayArea(&index);
// if the indexes do NOT match then the selection in the combobox
// was never updated, and therefore we should reset the the selection back to
// whatever it was before it was dropped down.
if (index != mSelectedIndex) {
ResetSelectedItem();
}
}
return NS_OK;
}

View File

@ -115,6 +115,23 @@ public:
*/
NS_IMETHOD SetFrameConstructor(nsCSSFrameConstructor *aConstructor) = 0;
/**
* This returns the index of the item that is currently being displayed
* in the display area. It may differ from what the currently Selected index
* is in in the dropdown.
*
* Detailed explanation:
* When the dropdown is dropped down via a mouse click and the user moves the mouse
* up and down without clicking, the currently selected item is being tracking inside
* the dropdown, but the combobox is not being updated. When the user selects items
* with the arrow keys, the combobox is being updated. So when the user clicks outside
* the dropdown and it needs to roll up it has to decide whether to keep the current
* selection or not. This method is used to get the current index in the combobox to
* compare it to the current index in the dropdown to see if the combox has been updated
* and that way it knows whether to "cancel" the the current selection residing in the
* dropdown. Or whether to leave the selection alone.
*/
NS_IMETHOD GetIndexOfDisplayArea(PRInt32* aSelectedIndex) = 0;
};
#endif

View File

@ -1939,6 +1939,13 @@ nsComboboxControlFrame::SelectionChanged()
return rv;
}
NS_IMETHODIMP
nsComboboxControlFrame::GetIndexOfDisplayArea(PRInt32* aSelectedIndex)
{
NS_ENSURE_ARG_POINTER(aSelectedIndex);
*aSelectedIndex = mSelectedIndex;
return NS_OK;
}
//----------------------------------------------------------------------
// nsISelectControlFrame

View File

@ -166,6 +166,7 @@ public:
NS_IMETHOD UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, PRInt32 aNewIndex);
NS_IMETHOD AbsolutelyPositionDropDown();
NS_IMETHOD GetAbsoluteRect(nsRect* aRect);
NS_IMETHOD GetIndexOfDisplayArea(PRInt32* aSelectedIndex);
// nsISelectControlFrame
NS_IMETHOD AddOption(nsIPresContext* aPresContext, PRInt32 index);

View File

@ -2847,10 +2847,30 @@ nsListControlFrame::AboutToDropDown()
NS_IMETHODIMP
nsListControlFrame::AboutToRollup()
{
// XXX By uncommenting this line below the "act" of rolling up
// will reset the the contents of the combobox to it's original contents
// (i.e. the contents before it was dropped down
ResetSelectedItem();
// XXX To have clicking outside the combobox ALWAYS reset the contents to the
// state before it was dropped, remove the all the code in the "if" below and replace it
// with just the call to ResetSelectedItem()
//
//
// When the dropdown is dropped down via a mouse click and the user moves the mouse
// up and down without clicking, the currently selected item is being tracking inside
// the dropdown, but the combobox is not being updated. When the user selects items
// with the arrow keys, the combobox is being updated. So when the user clicks outside
// the dropdown and it needs to roll up it has to decide whether to keep the current
// selection or not. The GetIndexOfDisplayArea method is used to get the current index
// in the combobox to compare it to the current index in the dropdown to see if the combox
// has been updated and that way it knows whether to "cancel" the the current selection
// residing in the dropdown. Or whether to leave the selection alone.
if (IsInDropDownMode() == PR_TRUE) {
PRInt32 index;
mComboboxFrame->GetIndexOfDisplayArea(&index);
// if the indexes do NOT match then the selection in the combobox
// was never updated, and therefore we should reset the the selection back to
// whatever it was before it was dropped down.
if (index != mSelectedIndex) {
ResetSelectedItem();
}
}
return NS_OK;
}