Completely reworked the select GFX object - List and Combobox, it now does all event processing

via DOM listeners instead of through the frames
This commit is contained in:
rods%netscape.com 1999-08-26 14:54:07 +00:00
Родитель 271b4483c7
Коммит 6cf112a833
10 изменённых файлов: 1436 добавлений и 1000 удалений

Просмотреть файл

@ -126,7 +126,7 @@ nsComboboxControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
return NS_OK;
} else if (aIID.Equals(kIDOMMouseListenerIID)) {
*aInstancePtr = (void*)(nsIDOMMouseListener*) this;
NS_ADDREF_THIS();
NS_ADDREF_THIS();
return NS_OK;
} else if (aIID.Equals(nsCOMTypeInfo<nsIDOMFocusListener>::GetIID())) {
*aInstancePtr = (void*)(nsIDOMFocusListener*)this;
@ -134,8 +134,10 @@ nsComboboxControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
return NS_OK;
} else if (aIID.Equals(kIAnonymousContentCreatorIID)) {
*aInstancePtr = (void*)(nsIAnonymousContentCreator*) this;
NS_ADDREF_THIS();
return NS_OK;
} else if (aIID.Equals(nsCOMTypeInfo<nsISelectControlFrame>::GetIID())) {
*aInstancePtr = (void *)((nsISelectControlFrame*)this);
return NS_OK;
}
return nsAreaFrame::QueryInterface(aIID, aInstancePtr);
@ -314,18 +316,6 @@ nsComboboxControlFrame::ScrollIntoView(nsIPresContext* aPresContext)
}
}
// Toggle dropdown list.
void
nsComboboxControlFrame::ToggleList(nsIPresContext* aPresContext)
{
if (PR_TRUE == mDroppedDown) {
ShowList(aPresContext, PR_FALSE);
} else {
ShowList(aPresContext, PR_TRUE);
}
}
void
nsComboboxControlFrame::ShowPopup(PRBool aShowPopup)
@ -508,11 +498,7 @@ nsComboboxControlFrame::PositionDropdown(nsIPresContext& aPresContext,
nscoord screenHeightInPixels = 0;
if (NS_SUCCEEDED(GetScreenHeight(aPresContext, screenHeightInPixels))) {
nsRect absoluteRect;
// Get the height of the dropdown list in pixels.
nsRect dropdownRect;
dropdownFrame->GetRect(dropdownRect);
// Get the height of the dropdown list in pixels.
float t2p;
aPresContext.GetTwipsToPixels(&t2p);
nscoord absoluteDropDownHeight = NSTwipsToIntPixels(dropdownRect.height, t2p);
@ -691,8 +677,8 @@ nsComboboxControlFrame::Reflow(nsIPresContext& aPresContext,
buttonFrame->GetRect(buttonRect);
if ((oldDisplayRect == displayRect) && (oldButtonRect == buttonRect)) {
// Reposition the popup.
nsRect absoluteTwips;
nsRect absolutePixels;
//nsRect absoluteTwips;
//nsRect absolutePixels;
//GetAbsoluteFramePosition(aPresContext, displayFrame, absoluteTwips, absolutePixels);
//PositionDropdown(aPresContext, displayRect.height, absoluteTwips, absolutePixels);
return rv;
@ -907,7 +893,7 @@ nsComboboxControlFrame::ReResolveStyleContext(nsIPresContext* aPresContext,
nsresult
nsComboboxControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
{
if (nsFormFrame::GetDisabled(this)) {
/*if (nsFormFrame::GetDisabled(this)) {
return NS_OK;
}
nsRect absoluteTwips;
@ -920,12 +906,40 @@ nsComboboxControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
PositionDropdown(*mPresContext, displayRect.height, absoluteTwips, absolutePixels);
ToggleList(mPresContext);
mIgnoreMouseUp = PR_TRUE;
*/
return NS_OK;
}
//----------------------------------------------------------------------
// nsIComboboxControlFrame
//----------------------------------------------------------------------
NS_IMETHODIMP
nsComboboxControlFrame::ShowDropDown(PRBool aDoDropDown)
{
if (nsFormFrame::GetDisabled(this)) {
return NS_OK;
}
if (!mDroppedDown && aDoDropDown) {
nsRect absoluteTwips;
nsRect absolutePixels;
nsIFrame * displayFrame = GetDisplayFrame(*mPresContext);
nsRect displayRect;
// Get the current sizes of the combo box child frames
displayFrame->GetRect(displayRect);
GetAbsoluteFramePosition(*mPresContext, displayFrame, absoluteTwips, absolutePixels);
PositionDropdown(*mPresContext, displayRect.height, absoluteTwips, absolutePixels);
ToggleList(mPresContext);
return NS_OK;
} else if (mDroppedDown && !aDoDropDown) {
ToggleList(mPresContext);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsComboboxControlFrame::SetDropDown(nsIFrame* aDropDownFrame)
@ -951,9 +965,60 @@ nsComboboxControlFrame::GetDropDown(nsIFrame** aDropDownFrame)
return NS_OK;
}
NS_IMETHODIMP
nsComboboxControlFrame::ListWasSelected(nsIPresContext* aPresContext)
{
if (aPresContext == nsnull) {
aPresContext = mPresContext;
}
ShowList(aPresContext, PR_FALSE);
mListControlFrame->CaptureMouseEvents(PR_FALSE);
void
nsComboboxControlFrame::SelectionChanged()
PRInt32 index;
mListControlFrame->GetSelectedIndex(&index);
UpdateSelection(PR_TRUE, PR_FALSE, index);
return NS_OK;
}
// Toggle dropdown list.
NS_IMETHODIMP
nsComboboxControlFrame::ToggleList(nsIPresContext* aPresContext)
{
if (PR_TRUE == mDroppedDown) {
ShowList(aPresContext, PR_FALSE);
} else {
ShowList(aPresContext, PR_TRUE);
}
return NS_OK;
}
NS_IMETHODIMP
nsComboboxControlFrame::UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, PRInt32 aNewIndex)
{
if (nsnull != mListControlFrame) {
// Check to see if the selection changed
if (mSelectedIndex != aNewIndex || aForceUpdate) {
nsAutoString newTextStr;
mListControlFrame->GetSelectedItem(newTextStr);
//XXX:TODO look at the ordinal position of the selected content in the listbox to tell
// if the selection has changed, rather than looking at the text string.
// There may be more than one item in the dropdown list with the same label.
if (newTextStr != mTextStr) {
mTextStr = newTextStr;
SelectionChanged(aDoDispatchEvent);
}
}
mSelectedIndex = aNewIndex;
}
return NS_OK;
}
NS_IMETHODIMP
nsComboboxControlFrame::SelectionChanged(PRBool aDoDispatchEvent)
{
if (nsnull != mDisplayContent) {
mDisplayContent->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, mTextStr, PR_TRUE);
@ -974,25 +1039,60 @@ nsComboboxControlFrame::SelectionChanged()
}
}
// Dispatch the NS_FORM_CHANGE event
nsEventStatus status = nsEventStatus_eIgnore;
nsGUIEvent event;
event.eventStructType = NS_GUI_EVENT;
event.widget = nsnull;
event.message = NS_FORM_CHANGE;
if (aDoDispatchEvent) {
// Dispatch the NS_FORM_CHANGE event
nsEventStatus status = nsEventStatus_eIgnore;
nsGUIEvent event;
event.eventStructType = NS_GUI_EVENT;
event.widget = nsnull;
event.message = NS_FORM_CHANGE;
// Have the content handle the event.
mContent->HandleDOMEvent(*mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
// Now have the frame handle the event
nsIFrame* frame = nsnull;
nsIFrame* dropdownFrame = GetDropdownFrame();
nsresult result = dropdownFrame->QueryInterface(kIFrameIID, (void**)&frame);
if ((NS_SUCCEEDED(result)) && (nsnull != frame)) {
frame->HandleEvent(*mPresContext, &event, status);
// Have the content handle the event.
mContent->HandleDOMEvent(*mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
// Now have the frame handle the event
nsIFrame* frame = nsnull;
nsIFrame* dropdownFrame = GetDropdownFrame();
nsresult result = dropdownFrame->QueryInterface(kIFrameIID, (void**)&frame);
if ((NS_SUCCEEDED(result)) && (nsnull != frame)) {
frame->HandleEvent(*mPresContext, &event, status);
}
}
return NS_OK;
}
//----------------------------------------------------------------------
// nsISelectControlFrame
//----------------------------------------------------------------------
NS_IMETHODIMP
nsComboboxControlFrame::AddOption(PRInt32 index)
{
nsISelectControlFrame* listFrame = nsnull;
nsIFrame* dropdownFrame = GetDropdownFrame();
nsresult rv = dropdownFrame->QueryInterface(nsCOMTypeInfo<nsISelectControlFrame>::GetIID(),
(void**)&listFrame);
if (NS_SUCCEEDED(rv) && nsnull != listFrame) {
return listFrame->AddOption(index);
}
return rv;
}
NS_IMETHODIMP
nsComboboxControlFrame::RemoveOption(PRInt32 index)
{
nsISelectControlFrame* listFrame = nsnull;
nsIFrame* dropdownFrame = GetDropdownFrame();
nsresult rv = dropdownFrame->QueryInterface(nsCOMTypeInfo<nsISelectControlFrame>::GetIID(),
(void**)&listFrame);
if (NS_SUCCEEDED(rv) && nsnull != listFrame) {
return listFrame->RemoveOption(index);
}
return rv;
}
NS_IMETHODIMP
nsComboboxControlFrame::HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
@ -1009,30 +1109,6 @@ nsComboboxControlFrame::HandleEvent(nsIPresContext& aPresContext,
}
NS_IMETHODIMP
nsComboboxControlFrame::ListWasSelected(nsIPresContext* aPresContext)
{
ShowList(aPresContext, PR_FALSE);
mListControlFrame->CaptureMouseEvents(PR_FALSE);
if (nsnull != mListControlFrame) {
PRInt32 index;
mListControlFrame->GetSelectedIndex(&index);
// Check to see if the selection changed
if (mSelectedIndex != index) {
mListControlFrame->GetSelectedItem(mTextStr);
mSelectedIndex = index;
//XXX:TODO look at the ordinal position of the selected content in the listbox to tell
// if the selection has changed, rather than looking at the text string.
// There may be more than one item in the dropdown list with the same label.
SelectionChanged();
}
}
return NS_OK;
}
nsresult
nsComboboxControlFrame::RequiresWidget(PRBool& aRequiresWidget)
{

Просмотреть файл

@ -27,6 +27,7 @@
#include "nsIDOMFocusListener.h"
#include "nsVoidArray.h"
#include "nsIAnonymousContentCreator.h"
#include "nsISelectControlFrame.h"
class nsButtonControlFrame;
class nsTextControlFrame;
@ -47,7 +48,8 @@ class nsComboboxControlFrame : public nsAreaFrame,
public nsIComboboxControlFrame,
public nsIDOMMouseListener,
public nsIDOMFocusListener,
public nsIAnonymousContentCreator
public nsIAnonymousContentCreator,
public nsISelectControlFrame
{
public:
@ -123,22 +125,33 @@ public:
nscoord aCharWidth) const;
virtual nsresult RequiresWidget(PRBool &aRequiresWidget);
NS_IMETHOD SelectionChanged(PRBool aDoDispatchEvent);// Called when the selection has changed.
// If the the same item in the list is selected
// it is NOT called.
// nsIFormMouseListener
virtual void MouseClicked(nsIPresContext* aPresContext);
//nsIComboboxControlFrame
NS_IMETHOD IsDroppedDown(PRBool * aDoDropDown) { *aDoDropDown = mDroppedDown; return NS_OK; }
NS_IMETHOD ShowDropDown(PRBool aDoDropDown);
NS_IMETHOD GetDropDown(nsIFrame** aDropDownFrame);
NS_IMETHOD SetDropDown(nsIFrame* aDropDownFrame);
NS_IMETHOD ListWasSelected(nsIPresContext* aPresContext);
NS_IMETHOD UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, PRInt32 aNewIndex);
// nsISelectControlFrame
NS_IMETHOD AddOption(PRInt32 index);
NS_IMETHOD RemoveOption(PRInt32 index);
//nsIDOMEventListener
virtual nsresult MouseDown(nsIDOMEvent* aMouseEvent);
virtual nsresult MouseUp(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseClick(nsIDOMEvent* aMouseEvent) { printf("mouse clock\n"); return NS_OK; };
virtual nsresult MouseUp(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseClick(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseDblClick(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; }
virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; }
//nsIDOMFocusListener
virtual nsresult Focus(nsIDOMEvent* aEvent);
@ -167,7 +180,6 @@ protected:
nsIFrame *aFrame,
nsRect& aAbsoluteTwipsRect,
nsRect& aAbsolutePixelRect);
void ToggleList(nsIPresContext* aPresContext);
void ShowPopup(PRBool aShowPopup);
void ShowList(nsIPresContext* aPresContext, PRBool aShowList);
void SetChildFrameSize(nsIFrame* aFrame, nscoord aWidth, nscoord aHeight);
@ -176,10 +188,8 @@ protected:
nsIFrame* GetButtonFrame(nsIPresContext& aPresContext);
nsIFrame* GetDisplayFrame(nsIPresContext& aPresContext);
nsIFrame* GetDropdownFrame();
NS_IMETHOD ToggleList(nsIPresContext* aPresContext);
// Called when the selection has changed. If the the same item in the list is selected
// it is NOT called.
void SelectionChanged();
nsFrameList mPopupFrames; // additional named child list
nsIPresContext* mPresContext; // XXX: Remove the need to cache the pres context.

Просмотреть файл

@ -44,6 +44,18 @@ class nsIComboboxControlFrame : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ICOMBOBOXCONTROLFRAME_IID)
/**
* Indicates whether the list is dropped down
*
*/
NS_IMETHOD IsDroppedDown(PRBool * aDoDropDown) = 0;
/**
* Shows or hides the drop down
*
*/
NS_IMETHOD ShowDropDown(PRBool aDoDropDown) = 0;
/**
* Gets the Drop Down List
*
@ -62,6 +74,15 @@ public:
*/
NS_IMETHOD ListWasSelected(nsIPresContext* aPresContext) = 0;
/**
* Asks the Combobox to update the display frame
* aDoDispatchEvent - indicates whether an event should be dispatched to the DOM
* aForceUpdate - indicates whether the indexx and the text value should both be
* whether the index has changed or not.
*
*/
NS_IMETHOD UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, PRInt32 aNewIndex) = 0;
};

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -22,12 +22,16 @@
#include "nsScrollFrame.h"
#include "nsIFormControlFrame.h"
#include "nsIListControlFrame.h"
#include "nsISelectControlFrame.h"
#include "nsIDOMMouseListener.h"
#include "nsIDOMMouseMotionListener.h"
class nsIDOMHTMLSelectElement;
class nsIDOMHTMLCollection;
class nsIDOMHTMLOptionElement;
class nsIComboboxControlFrame;
class nsIViewManager;
class nsIPresContext;
/**
* Frame-based listbox.
@ -35,7 +39,10 @@ class nsIViewManager;
class nsListControlFrame : public nsScrollFrame,
public nsIFormControlFrame,
public nsIListControlFrame
public nsIListControlFrame,
public nsIDOMMouseListener,
public nsIDOMMouseMotionListener,
public nsISelectControlFrame
{
public:
friend nsresult NS_NewListControlFrame(nsIFrame** aNewFrame);
@ -44,8 +51,6 @@ public:
NS_DECL_ISUPPORTS
// nsIFrame
NS_IMETHOD GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame);
NS_IMETHOD HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
@ -99,13 +104,31 @@ public:
// nsIListControlFrame
NS_IMETHOD SetComboboxFrame(nsIFrame* aComboboxFrame);
NS_IMETHOD GetSelectedIndex(PRInt32* aIndex);
NS_IMETHOD GetSelectedItem(nsString & aStr);
NS_IMETHOD GetSelectedIndex(PRInt32* aIndex);
NS_IMETHOD CaptureMouseEvents(PRBool aGrabMouseEvents);
NS_IMETHOD GetMaximumSize(nsSize &aSize);
NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight);
NS_IMETHOD GetNumberOfOptions(PRInt32* aNumOptions);
// nsISelectControlFrame
NS_IMETHOD AddOption(PRInt32 index);
NS_IMETHOD RemoveOption(PRInt32 index);
//nsIDOMEventListener
virtual nsresult MouseDown(nsIDOMEvent* aMouseEvent);//{ printf("-MouseDown\n"); return NS_OK; };
virtual nsresult MouseUp(nsIDOMEvent* aMouseEvent);// { printf("-MouseUp\n"); return NS_OK; };
virtual nsresult MouseClick(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseDblClick(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; }
//nsIDOMEventMotionListener
virtual nsresult MouseMove(nsIDOMEvent* aMouseEvent);
virtual nsresult DragMove(nsIDOMEvent* aMouseEvent) { return NS_OK; }
// Static Methods
static nsIDOMHTMLSelectElement* GetSelect(nsIContent * aContent);
static nsIDOMHTMLCollection* GetOptions(nsIContent * aContent, nsIDOMHTMLSelectElement* aSelect = nsnull);
@ -114,6 +137,7 @@ public:
static PRBool GetOptionValue(nsIDOMHTMLCollection& aCollecton, PRUint32 aIndex, nsString& aValue);
protected:
NS_IMETHOD GetSelectedIndexFromDOM(PRInt32* aIndex); // from DOM
nsListControlFrame();
virtual ~nsListControlFrame();
@ -128,16 +152,16 @@ protected:
// Utility methods
nsresult GetSizeAttribute(PRInt32 *aSize);
PRInt32 GetNumberOfSelections();
nsIContent* GetOptionFromContent(nsIContent *aContent);
nsresult GetIndexFromDOMEvent(nsIDOMEvent* aMouseEvent);
PRInt32 GetSelectedIndexFromContent(nsIContent *aContent);
nsIContent* GetOptionContent(PRUint32 aIndex);
PRBool IsContentSelected(nsIContent* aContent);
PRBool IsFrameSelected(PRUint32 aIndex);
void SetFrameSelected(PRUint32 aIndex, PRBool aSelected);
PRBool IsContentSelectedByIndex(PRUint32 aIndex);
void SetContentSelected(PRUint32 aIndex, PRBool aSelected);
void GetViewOffset(nsIViewManager* aManager, nsIView* aView, nsPoint& aPoint);
nsresult Deselect();
nsIFrame *GetOptionFromChild(nsIFrame* aParentFrame);
nsresult GetFrameForPointUsing(const nsPoint& aPoint,
nsIAtom* aList,
nsIFrame** aFrame);
PRBool IsAncestor(nsIView* aAncestor, nsIView* aChild);
nsIView* GetViewFor(nsIWidget* aWidget);
nsresult SyncViewWithFrame();
@ -156,22 +180,15 @@ protected:
void ClearSelection();
void ExtendedSelection(PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aDoInvert, PRBool aSetValue);
nsresult HandleLikeDropDownListEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
PRBool HasSameContent(nsIFrame* aFrame1, nsIFrame* aFrame2);
void HandleListSelection(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
nsresult HandleLikeListEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
void HandleListSelection(nsIDOMEvent * aDOMEvent);
PRInt32 GetSelectedIndexFromFrame(nsIFrame *aHitFrame);
// Data Members
nscoord mBorderOffsetY;
nsFormFrame* mFormFrame;
PRInt32 mSelectedIndex;
PRInt32 mOldSelectedIndex;
PRInt32 mStartExtendedIndex;
PRInt32 mEndExtendedIndex;
nsIFrame* mHitFrame;
@ -184,6 +201,9 @@ protected:
nscoord mMaxWidth;
nscoord mMaxHeight;
PRBool mIsCapturingMouseEvents;
PRBool mIgnoreMouseUp;
nsIPresContext* mPresContext; // XXX: Remove the need to cache the pres context.
// XXX temprary only until full system mouse capture works
PRBool mIsScrollbarVisible;

Просмотреть файл

@ -44,6 +44,18 @@ class nsIComboboxControlFrame : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ICOMBOBOXCONTROLFRAME_IID)
/**
* Indicates whether the list is dropped down
*
*/
NS_IMETHOD IsDroppedDown(PRBool * aDoDropDown) = 0;
/**
* Shows or hides the drop down
*
*/
NS_IMETHOD ShowDropDown(PRBool aDoDropDown) = 0;
/**
* Gets the Drop Down List
*
@ -62,6 +74,15 @@ public:
*/
NS_IMETHOD ListWasSelected(nsIPresContext* aPresContext) = 0;
/**
* Asks the Combobox to update the display frame
* aDoDispatchEvent - indicates whether an event should be dispatched to the DOM
* aForceUpdate - indicates whether the indexx and the text value should both be
* whether the index has changed or not.
*
*/
NS_IMETHOD UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, PRInt32 aNewIndex) = 0;
};

Просмотреть файл

@ -126,7 +126,7 @@ nsComboboxControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
return NS_OK;
} else if (aIID.Equals(kIDOMMouseListenerIID)) {
*aInstancePtr = (void*)(nsIDOMMouseListener*) this;
NS_ADDREF_THIS();
NS_ADDREF_THIS();
return NS_OK;
} else if (aIID.Equals(nsCOMTypeInfo<nsIDOMFocusListener>::GetIID())) {
*aInstancePtr = (void*)(nsIDOMFocusListener*)this;
@ -134,8 +134,10 @@ nsComboboxControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
return NS_OK;
} else if (aIID.Equals(kIAnonymousContentCreatorIID)) {
*aInstancePtr = (void*)(nsIAnonymousContentCreator*) this;
NS_ADDREF_THIS();
return NS_OK;
} else if (aIID.Equals(nsCOMTypeInfo<nsISelectControlFrame>::GetIID())) {
*aInstancePtr = (void *)((nsISelectControlFrame*)this);
return NS_OK;
}
return nsAreaFrame::QueryInterface(aIID, aInstancePtr);
@ -314,18 +316,6 @@ nsComboboxControlFrame::ScrollIntoView(nsIPresContext* aPresContext)
}
}
// Toggle dropdown list.
void
nsComboboxControlFrame::ToggleList(nsIPresContext* aPresContext)
{
if (PR_TRUE == mDroppedDown) {
ShowList(aPresContext, PR_FALSE);
} else {
ShowList(aPresContext, PR_TRUE);
}
}
void
nsComboboxControlFrame::ShowPopup(PRBool aShowPopup)
@ -508,11 +498,7 @@ nsComboboxControlFrame::PositionDropdown(nsIPresContext& aPresContext,
nscoord screenHeightInPixels = 0;
if (NS_SUCCEEDED(GetScreenHeight(aPresContext, screenHeightInPixels))) {
nsRect absoluteRect;
// Get the height of the dropdown list in pixels.
nsRect dropdownRect;
dropdownFrame->GetRect(dropdownRect);
// Get the height of the dropdown list in pixels.
float t2p;
aPresContext.GetTwipsToPixels(&t2p);
nscoord absoluteDropDownHeight = NSTwipsToIntPixels(dropdownRect.height, t2p);
@ -691,8 +677,8 @@ nsComboboxControlFrame::Reflow(nsIPresContext& aPresContext,
buttonFrame->GetRect(buttonRect);
if ((oldDisplayRect == displayRect) && (oldButtonRect == buttonRect)) {
// Reposition the popup.
nsRect absoluteTwips;
nsRect absolutePixels;
//nsRect absoluteTwips;
//nsRect absolutePixels;
//GetAbsoluteFramePosition(aPresContext, displayFrame, absoluteTwips, absolutePixels);
//PositionDropdown(aPresContext, displayRect.height, absoluteTwips, absolutePixels);
return rv;
@ -907,7 +893,7 @@ nsComboboxControlFrame::ReResolveStyleContext(nsIPresContext* aPresContext,
nsresult
nsComboboxControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
{
if (nsFormFrame::GetDisabled(this)) {
/*if (nsFormFrame::GetDisabled(this)) {
return NS_OK;
}
nsRect absoluteTwips;
@ -920,12 +906,40 @@ nsComboboxControlFrame::MouseDown(nsIDOMEvent* aMouseEvent)
PositionDropdown(*mPresContext, displayRect.height, absoluteTwips, absolutePixels);
ToggleList(mPresContext);
mIgnoreMouseUp = PR_TRUE;
*/
return NS_OK;
}
//----------------------------------------------------------------------
// nsIComboboxControlFrame
//----------------------------------------------------------------------
NS_IMETHODIMP
nsComboboxControlFrame::ShowDropDown(PRBool aDoDropDown)
{
if (nsFormFrame::GetDisabled(this)) {
return NS_OK;
}
if (!mDroppedDown && aDoDropDown) {
nsRect absoluteTwips;
nsRect absolutePixels;
nsIFrame * displayFrame = GetDisplayFrame(*mPresContext);
nsRect displayRect;
// Get the current sizes of the combo box child frames
displayFrame->GetRect(displayRect);
GetAbsoluteFramePosition(*mPresContext, displayFrame, absoluteTwips, absolutePixels);
PositionDropdown(*mPresContext, displayRect.height, absoluteTwips, absolutePixels);
ToggleList(mPresContext);
return NS_OK;
} else if (mDroppedDown && !aDoDropDown) {
ToggleList(mPresContext);
return NS_OK;
}
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsComboboxControlFrame::SetDropDown(nsIFrame* aDropDownFrame)
@ -951,9 +965,60 @@ nsComboboxControlFrame::GetDropDown(nsIFrame** aDropDownFrame)
return NS_OK;
}
NS_IMETHODIMP
nsComboboxControlFrame::ListWasSelected(nsIPresContext* aPresContext)
{
if (aPresContext == nsnull) {
aPresContext = mPresContext;
}
ShowList(aPresContext, PR_FALSE);
mListControlFrame->CaptureMouseEvents(PR_FALSE);
void
nsComboboxControlFrame::SelectionChanged()
PRInt32 index;
mListControlFrame->GetSelectedIndex(&index);
UpdateSelection(PR_TRUE, PR_FALSE, index);
return NS_OK;
}
// Toggle dropdown list.
NS_IMETHODIMP
nsComboboxControlFrame::ToggleList(nsIPresContext* aPresContext)
{
if (PR_TRUE == mDroppedDown) {
ShowList(aPresContext, PR_FALSE);
} else {
ShowList(aPresContext, PR_TRUE);
}
return NS_OK;
}
NS_IMETHODIMP
nsComboboxControlFrame::UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, PRInt32 aNewIndex)
{
if (nsnull != mListControlFrame) {
// Check to see if the selection changed
if (mSelectedIndex != aNewIndex || aForceUpdate) {
nsAutoString newTextStr;
mListControlFrame->GetSelectedItem(newTextStr);
//XXX:TODO look at the ordinal position of the selected content in the listbox to tell
// if the selection has changed, rather than looking at the text string.
// There may be more than one item in the dropdown list with the same label.
if (newTextStr != mTextStr) {
mTextStr = newTextStr;
SelectionChanged(aDoDispatchEvent);
}
}
mSelectedIndex = aNewIndex;
}
return NS_OK;
}
NS_IMETHODIMP
nsComboboxControlFrame::SelectionChanged(PRBool aDoDispatchEvent)
{
if (nsnull != mDisplayContent) {
mDisplayContent->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, mTextStr, PR_TRUE);
@ -974,25 +1039,60 @@ nsComboboxControlFrame::SelectionChanged()
}
}
// Dispatch the NS_FORM_CHANGE event
nsEventStatus status = nsEventStatus_eIgnore;
nsGUIEvent event;
event.eventStructType = NS_GUI_EVENT;
event.widget = nsnull;
event.message = NS_FORM_CHANGE;
if (aDoDispatchEvent) {
// Dispatch the NS_FORM_CHANGE event
nsEventStatus status = nsEventStatus_eIgnore;
nsGUIEvent event;
event.eventStructType = NS_GUI_EVENT;
event.widget = nsnull;
event.message = NS_FORM_CHANGE;
// Have the content handle the event.
mContent->HandleDOMEvent(*mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
// Now have the frame handle the event
nsIFrame* frame = nsnull;
nsIFrame* dropdownFrame = GetDropdownFrame();
nsresult result = dropdownFrame->QueryInterface(kIFrameIID, (void**)&frame);
if ((NS_SUCCEEDED(result)) && (nsnull != frame)) {
frame->HandleEvent(*mPresContext, &event, status);
// Have the content handle the event.
mContent->HandleDOMEvent(*mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, status);
// Now have the frame handle the event
nsIFrame* frame = nsnull;
nsIFrame* dropdownFrame = GetDropdownFrame();
nsresult result = dropdownFrame->QueryInterface(kIFrameIID, (void**)&frame);
if ((NS_SUCCEEDED(result)) && (nsnull != frame)) {
frame->HandleEvent(*mPresContext, &event, status);
}
}
return NS_OK;
}
//----------------------------------------------------------------------
// nsISelectControlFrame
//----------------------------------------------------------------------
NS_IMETHODIMP
nsComboboxControlFrame::AddOption(PRInt32 index)
{
nsISelectControlFrame* listFrame = nsnull;
nsIFrame* dropdownFrame = GetDropdownFrame();
nsresult rv = dropdownFrame->QueryInterface(nsCOMTypeInfo<nsISelectControlFrame>::GetIID(),
(void**)&listFrame);
if (NS_SUCCEEDED(rv) && nsnull != listFrame) {
return listFrame->AddOption(index);
}
return rv;
}
NS_IMETHODIMP
nsComboboxControlFrame::RemoveOption(PRInt32 index)
{
nsISelectControlFrame* listFrame = nsnull;
nsIFrame* dropdownFrame = GetDropdownFrame();
nsresult rv = dropdownFrame->QueryInterface(nsCOMTypeInfo<nsISelectControlFrame>::GetIID(),
(void**)&listFrame);
if (NS_SUCCEEDED(rv) && nsnull != listFrame) {
return listFrame->RemoveOption(index);
}
return rv;
}
NS_IMETHODIMP
nsComboboxControlFrame::HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
@ -1009,30 +1109,6 @@ nsComboboxControlFrame::HandleEvent(nsIPresContext& aPresContext,
}
NS_IMETHODIMP
nsComboboxControlFrame::ListWasSelected(nsIPresContext* aPresContext)
{
ShowList(aPresContext, PR_FALSE);
mListControlFrame->CaptureMouseEvents(PR_FALSE);
if (nsnull != mListControlFrame) {
PRInt32 index;
mListControlFrame->GetSelectedIndex(&index);
// Check to see if the selection changed
if (mSelectedIndex != index) {
mListControlFrame->GetSelectedItem(mTextStr);
mSelectedIndex = index;
//XXX:TODO look at the ordinal position of the selected content in the listbox to tell
// if the selection has changed, rather than looking at the text string.
// There may be more than one item in the dropdown list with the same label.
SelectionChanged();
}
}
return NS_OK;
}
nsresult
nsComboboxControlFrame::RequiresWidget(PRBool& aRequiresWidget)
{

Просмотреть файл

@ -27,6 +27,7 @@
#include "nsIDOMFocusListener.h"
#include "nsVoidArray.h"
#include "nsIAnonymousContentCreator.h"
#include "nsISelectControlFrame.h"
class nsButtonControlFrame;
class nsTextControlFrame;
@ -47,7 +48,8 @@ class nsComboboxControlFrame : public nsAreaFrame,
public nsIComboboxControlFrame,
public nsIDOMMouseListener,
public nsIDOMFocusListener,
public nsIAnonymousContentCreator
public nsIAnonymousContentCreator,
public nsISelectControlFrame
{
public:
@ -123,22 +125,33 @@ public:
nscoord aCharWidth) const;
virtual nsresult RequiresWidget(PRBool &aRequiresWidget);
NS_IMETHOD SelectionChanged(PRBool aDoDispatchEvent);// Called when the selection has changed.
// If the the same item in the list is selected
// it is NOT called.
// nsIFormMouseListener
virtual void MouseClicked(nsIPresContext* aPresContext);
//nsIComboboxControlFrame
NS_IMETHOD IsDroppedDown(PRBool * aDoDropDown) { *aDoDropDown = mDroppedDown; return NS_OK; }
NS_IMETHOD ShowDropDown(PRBool aDoDropDown);
NS_IMETHOD GetDropDown(nsIFrame** aDropDownFrame);
NS_IMETHOD SetDropDown(nsIFrame* aDropDownFrame);
NS_IMETHOD ListWasSelected(nsIPresContext* aPresContext);
NS_IMETHOD UpdateSelection(PRBool aDoDispatchEvent, PRBool aForceUpdate, PRInt32 aNewIndex);
// nsISelectControlFrame
NS_IMETHOD AddOption(PRInt32 index);
NS_IMETHOD RemoveOption(PRInt32 index);
//nsIDOMEventListener
virtual nsresult MouseDown(nsIDOMEvent* aMouseEvent);
virtual nsresult MouseUp(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseClick(nsIDOMEvent* aMouseEvent) { printf("mouse clock\n"); return NS_OK; };
virtual nsresult MouseUp(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseClick(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseDblClick(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; }
virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; }
//nsIDOMFocusListener
virtual nsresult Focus(nsIDOMEvent* aEvent);
@ -167,7 +180,6 @@ protected:
nsIFrame *aFrame,
nsRect& aAbsoluteTwipsRect,
nsRect& aAbsolutePixelRect);
void ToggleList(nsIPresContext* aPresContext);
void ShowPopup(PRBool aShowPopup);
void ShowList(nsIPresContext* aPresContext, PRBool aShowList);
void SetChildFrameSize(nsIFrame* aFrame, nscoord aWidth, nscoord aHeight);
@ -176,10 +188,8 @@ protected:
nsIFrame* GetButtonFrame(nsIPresContext& aPresContext);
nsIFrame* GetDisplayFrame(nsIPresContext& aPresContext);
nsIFrame* GetDropdownFrame();
NS_IMETHOD ToggleList(nsIPresContext* aPresContext);
// Called when the selection has changed. If the the same item in the list is selected
// it is NOT called.
void SelectionChanged();
nsFrameList mPopupFrames; // additional named child list
nsIPresContext* mPresContext; // XXX: Remove the need to cache the pres context.

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -22,12 +22,16 @@
#include "nsScrollFrame.h"
#include "nsIFormControlFrame.h"
#include "nsIListControlFrame.h"
#include "nsISelectControlFrame.h"
#include "nsIDOMMouseListener.h"
#include "nsIDOMMouseMotionListener.h"
class nsIDOMHTMLSelectElement;
class nsIDOMHTMLCollection;
class nsIDOMHTMLOptionElement;
class nsIComboboxControlFrame;
class nsIViewManager;
class nsIPresContext;
/**
* Frame-based listbox.
@ -35,7 +39,10 @@ class nsIViewManager;
class nsListControlFrame : public nsScrollFrame,
public nsIFormControlFrame,
public nsIListControlFrame
public nsIListControlFrame,
public nsIDOMMouseListener,
public nsIDOMMouseMotionListener,
public nsISelectControlFrame
{
public:
friend nsresult NS_NewListControlFrame(nsIFrame** aNewFrame);
@ -44,8 +51,6 @@ public:
NS_DECL_ISUPPORTS
// nsIFrame
NS_IMETHOD GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame);
NS_IMETHOD HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
@ -99,13 +104,31 @@ public:
// nsIListControlFrame
NS_IMETHOD SetComboboxFrame(nsIFrame* aComboboxFrame);
NS_IMETHOD GetSelectedIndex(PRInt32* aIndex);
NS_IMETHOD GetSelectedItem(nsString & aStr);
NS_IMETHOD GetSelectedIndex(PRInt32* aIndex);
NS_IMETHOD CaptureMouseEvents(PRBool aGrabMouseEvents);
NS_IMETHOD GetMaximumSize(nsSize &aSize);
NS_IMETHOD SetSuggestedSize(nscoord aWidth, nscoord aHeight);
NS_IMETHOD GetNumberOfOptions(PRInt32* aNumOptions);
// nsISelectControlFrame
NS_IMETHOD AddOption(PRInt32 index);
NS_IMETHOD RemoveOption(PRInt32 index);
//nsIDOMEventListener
virtual nsresult MouseDown(nsIDOMEvent* aMouseEvent);//{ printf("-MouseDown\n"); return NS_OK; };
virtual nsresult MouseUp(nsIDOMEvent* aMouseEvent);// { printf("-MouseUp\n"); return NS_OK; };
virtual nsresult MouseClick(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseDblClick(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent) { return NS_OK; }
virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; }
//nsIDOMEventMotionListener
virtual nsresult MouseMove(nsIDOMEvent* aMouseEvent);
virtual nsresult DragMove(nsIDOMEvent* aMouseEvent) { return NS_OK; }
// Static Methods
static nsIDOMHTMLSelectElement* GetSelect(nsIContent * aContent);
static nsIDOMHTMLCollection* GetOptions(nsIContent * aContent, nsIDOMHTMLSelectElement* aSelect = nsnull);
@ -114,6 +137,7 @@ public:
static PRBool GetOptionValue(nsIDOMHTMLCollection& aCollecton, PRUint32 aIndex, nsString& aValue);
protected:
NS_IMETHOD GetSelectedIndexFromDOM(PRInt32* aIndex); // from DOM
nsListControlFrame();
virtual ~nsListControlFrame();
@ -128,16 +152,16 @@ protected:
// Utility methods
nsresult GetSizeAttribute(PRInt32 *aSize);
PRInt32 GetNumberOfSelections();
nsIContent* GetOptionFromContent(nsIContent *aContent);
nsresult GetIndexFromDOMEvent(nsIDOMEvent* aMouseEvent);
PRInt32 GetSelectedIndexFromContent(nsIContent *aContent);
nsIContent* GetOptionContent(PRUint32 aIndex);
PRBool IsContentSelected(nsIContent* aContent);
PRBool IsFrameSelected(PRUint32 aIndex);
void SetFrameSelected(PRUint32 aIndex, PRBool aSelected);
PRBool IsContentSelectedByIndex(PRUint32 aIndex);
void SetContentSelected(PRUint32 aIndex, PRBool aSelected);
void GetViewOffset(nsIViewManager* aManager, nsIView* aView, nsPoint& aPoint);
nsresult Deselect();
nsIFrame *GetOptionFromChild(nsIFrame* aParentFrame);
nsresult GetFrameForPointUsing(const nsPoint& aPoint,
nsIAtom* aList,
nsIFrame** aFrame);
PRBool IsAncestor(nsIView* aAncestor, nsIView* aChild);
nsIView* GetViewFor(nsIWidget* aWidget);
nsresult SyncViewWithFrame();
@ -156,22 +180,15 @@ protected:
void ClearSelection();
void ExtendedSelection(PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aDoInvert, PRBool aSetValue);
nsresult HandleLikeDropDownListEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
PRBool HasSameContent(nsIFrame* aFrame1, nsIFrame* aFrame2);
void HandleListSelection(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
nsresult HandleLikeListEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
void HandleListSelection(nsIDOMEvent * aDOMEvent);
PRInt32 GetSelectedIndexFromFrame(nsIFrame *aHitFrame);
// Data Members
nscoord mBorderOffsetY;
nsFormFrame* mFormFrame;
PRInt32 mSelectedIndex;
PRInt32 mOldSelectedIndex;
PRInt32 mStartExtendedIndex;
PRInt32 mEndExtendedIndex;
nsIFrame* mHitFrame;
@ -184,6 +201,9 @@ protected:
nscoord mMaxWidth;
nscoord mMaxHeight;
PRBool mIsCapturingMouseEvents;
PRBool mIgnoreMouseUp;
nsIPresContext* mPresContext; // XXX: Remove the need to cache the pres context.
// XXX temprary only until full system mouse capture works
PRBool mIsScrollbarVisible;