Enabled frame-based comboboxes when widget rendering mode is gfx.

Major changes to nsComboboxControlFrame:
Removed commented out code + nsIPluggableEventListener references.
Implemented nsComboboxControlFrame::GetNamesValues
Implemented nsComboboxControlFrame::SetProperty GetProperty methods
Fixed references to previously freed memory in nsComboboxControlFrame::ReResolveStyleContext
Modified ua.css style rules for dropdown-visible, drodown-hidden to have -moz- prefix.
Added -moz-dropdown-btn-out and -moz-dropdown-btn-pressed, -moz-dropdown-list rules.
Modified nsListControlFrame.cpp to calculate the width of the dropdown list for combo boxes correctly
Added nsListControlFrame::GetProperty and SetProperty methods.
Modified nsCSSFrameConstructor::ConstructSelectFrame to setup combobox.
This commit is contained in:
kmcclusk%netscape.com 1999-04-12 22:14:31 +00:00
Родитель 45abef6c49
Коммит a1fecd8f08
20 изменённых файлов: 732 добавлений и 630 удалений

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

@ -92,6 +92,7 @@ nsIAtom* nsHTMLAtoms::dropDownVisible;
nsIAtom* nsHTMLAtoms::dropDownHidden;
nsIAtom* nsHTMLAtoms::dropDownBtnOut;
nsIAtom* nsHTMLAtoms::dropDownBtnPressed;
nsIAtom* nsHTMLAtoms::dropDownList;
nsIAtom* nsHTMLAtoms::embed;
nsIAtom* nsHTMLAtoms::encoding;
nsIAtom* nsHTMLAtoms::enctype;
@ -344,10 +345,11 @@ void nsHTMLAtoms::AddrefAtoms()
div = NS_NewAtom("div");
disabled = NS_NewAtom("disabled");
dl = NS_NewAtom("dl");
dropDownVisible = NS_NewAtom(":dropdown-visible");
dropDownHidden = NS_NewAtom(":dropdown-hidden");
dropDownBtnOut = NS_NewAtom(":dropdown-btn-out");
dropDownBtnPressed = NS_NewAtom(":dropdown-btn-pressed");
dropDownVisible = NS_NewAtom(":-moz-dropdown-visible");
dropDownHidden = NS_NewAtom(":-moz-dropdown-hidden");
dropDownBtnOut = NS_NewAtom(":-moz-dropdown-btn-out");
dropDownBtnPressed = NS_NewAtom(":-moz-dropdown-btn-pressed");
dropDownList = NS_NewAtom(":-moz-dropdown-list");
datetime = NS_NewAtom("datetime");
data = NS_NewAtom("data");
embed = NS_NewAtom("embed");
@ -606,6 +608,7 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(dropDownHidden);
NS_RELEASE(dropDownBtnOut);
NS_RELEASE(dropDownBtnPressed);
NS_RELEASE(dropDownList);
NS_RELEASE(embed);
NS_RELEASE(encoding);
NS_RELEASE(face);

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

@ -114,6 +114,7 @@ public:
static nsIAtom* dropDownHidden;
static nsIAtom* dropDownBtnOut;
static nsIAtom* dropDownBtnPressed;
static nsIAtom* dropDownList;
static nsIAtom* embed;
static nsIAtom* encoding;

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

@ -114,6 +114,7 @@ public:
static nsIAtom* dropDownHidden;
static nsIAtom* dropDownBtnOut;
static nsIAtom* dropDownBtnPressed;
static nsIAtom* dropDownList;
static nsIAtom* embed;
static nsIAtom* encoding;

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

@ -92,6 +92,7 @@ nsIAtom* nsHTMLAtoms::dropDownVisible;
nsIAtom* nsHTMLAtoms::dropDownHidden;
nsIAtom* nsHTMLAtoms::dropDownBtnOut;
nsIAtom* nsHTMLAtoms::dropDownBtnPressed;
nsIAtom* nsHTMLAtoms::dropDownList;
nsIAtom* nsHTMLAtoms::embed;
nsIAtom* nsHTMLAtoms::encoding;
nsIAtom* nsHTMLAtoms::enctype;
@ -344,10 +345,11 @@ void nsHTMLAtoms::AddrefAtoms()
div = NS_NewAtom("div");
disabled = NS_NewAtom("disabled");
dl = NS_NewAtom("dl");
dropDownVisible = NS_NewAtom(":dropdown-visible");
dropDownHidden = NS_NewAtom(":dropdown-hidden");
dropDownBtnOut = NS_NewAtom(":dropdown-btn-out");
dropDownBtnPressed = NS_NewAtom(":dropdown-btn-pressed");
dropDownVisible = NS_NewAtom(":-moz-dropdown-visible");
dropDownHidden = NS_NewAtom(":-moz-dropdown-hidden");
dropDownBtnOut = NS_NewAtom(":-moz-dropdown-btn-out");
dropDownBtnPressed = NS_NewAtom(":-moz-dropdown-btn-pressed");
dropDownList = NS_NewAtom(":-moz-dropdown-list");
datetime = NS_NewAtom("datetime");
data = NS_NewAtom("data");
embed = NS_NewAtom("embed");
@ -606,6 +608,7 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(dropDownHidden);
NS_RELEASE(dropDownBtnOut);
NS_RELEASE(dropDownBtnPressed);
NS_RELEASE(dropDownList);
NS_RELEASE(embed);
NS_RELEASE(encoding);
NS_RELEASE(face);

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

@ -91,6 +91,8 @@ static NS_DEFINE_IID(kIDOMHTMLImageElementIID, NS_IDOMHTMLIMAGEELEMENT_IID);
static NS_DEFINE_IID(kIDOMCharacterDataIID, NS_IDOMCHARACTERDATA_IID);
static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
// Structure used when constructing formatting object trees.
struct nsFrameItems {
@ -2010,28 +2012,36 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContext,
PRBool aIsAbsolutelyPositioned,
PRBool & aFrameHasBeenInitialized,
PRBool aIsFixedPositioned,
nsAbsoluteItems& aFixedItems)
nsAbsoluteItems& aFixedItems,
nsFrameItems& aFrameItems)
{
#define NS_FRAME_BASED_COMBO_WORKS 0
nsresult rv = NS_OK;
nsWidgetRendering mode;
aPresContext->GetWidgetRenderingMode(&mode);
const PRInt32 kNoSizeSpecified = -1;
if (eWidgetRendering_Gfx == mode) {
// Construct a frame-based listbox or combobox
nsIDOMHTMLSelectElement* select = nsnull;
PRInt32 size = 1;
PRInt32 size = 1;
nsresult result = aContent->QueryInterface(kIDOMHTMLSelectElementIID, (void**)&select);
if (NS_OK == result) {
result = select->GetSize(&size);
if (1 == size) {
if (! NS_FRAME_BASED_COMBO_WORKS) {
rv = NS_NewSelectControlFrame(aNewFrame);
} else {
if ((1 == size) || (kNoSizeSpecified == size)) {
// Construct a frame-based combo box
nsIFrame * comboboxFrame;
rv = NS_NewComboboxControlFrame(comboboxFrame);
nsIComboboxControlFrame* comboBox;
if (NS_OK == comboboxFrame->QueryInterface(kIComboboxControlFrameIID, (void**)&comboBox)) {
nsIFrame* geometricParent = aParentFrame;
if (aIsAbsolutelyPositioned) {
geometricParent = aAbsoluteItems.containingBlock;
} else if (aIsFixedPositioned) {
geometricParent = aFixedItems.containingBlock;
}
comboboxFrame->Init(*aPresContext, aContent, geometricParent, aStyleContext, nsnull);
nsIComboboxControlFrame* comboBox = nsnull;
if (NS_OK == comboboxFrame->QueryInterface(kIComboboxControlFrameIID, (void**)&comboBox)) {
nsIFrame * listFrame;
rv = NS_NewListControlFrame(listFrame);
@ -2042,19 +2052,53 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContext,
listControlFrame->SetComboboxFrame(comboboxFrame);
}
InitializeScrollFrame(listFrame, aPresContext, aContent, comboboxFrame, aStyleContext,
aAbsoluteItems, aNewFrame, aFixedItems, aIsAbsolutelyPositioned,
aIsFixedPositioned, PR_TRUE);
//XXX: TODO: Make sure that a failure to resolve the following
//pseudo style will still work.
nsIFrame* placeholderFrame;
// Set up the Pseudo Style contents
// Dropdown list style
nsCOMPtr<nsIStyleContext> listStyle;
aPresContext->ResolvePseudoStyleContextFor
(aContent, nsHTMLAtoms::dropDownList, aStyleContext, PR_FALSE,
getter_AddRefs(listStyle));
// Dropdown list visible style
nsCOMPtr<nsIStyleContext> visiblePseudoStyle;
aPresContext->ResolvePseudoStyleContextFor
(aContent, nsHTMLAtoms::dropDownVisible, aStyleContext, PR_FALSE,
getter_AddRefs(visiblePseudoStyle));
// Dropdown list hidden style
nsCOMPtr<nsIStyleContext> hiddenPseudoStyle;
aPresContext->ResolvePseudoStyleContextFor
(aContent, nsHTMLAtoms::dropDownHidden, aStyleContext, PR_FALSE,
getter_AddRefs(hiddenPseudoStyle));
// Initialize the scroll frame as absolutely positioned.
InitializeScrollFrame(listFrame, aPresContext, aContent, comboboxFrame, listStyle,
aAbsoluteItems, aNewFrame, aFixedItems, PR_TRUE,
PR_FALSE, PR_TRUE);
// Set flag so the events go to the listFrame not child frames.
// XXX: We should replace this with a real widget manager similar
// to how the nsFormControlFrame works.
// Re-directing events is a temporary Kludge.
nsIView *listView;
listFrame->GetView(&listView);
NS_ASSERTION(nsnull != listView,"ListFrame's view is nsnull");
listView->SetViewFlags(NS_VIEW_FLAG_DONT_CHECK_CHILDREN);
// Create a place holder frame for the dropdown list
nsIFrame* placeholderFrame = nsnull;
CreatePlaceholderFrameFor(aPresContext, aContent, aNewFrame, aStyleContext,
aParentFrame, placeholderFrame);
aFrameItems.AddChild(placeholderFrame);
// Add the absolutely positioned frame to its containing block's list
// of child frames
if (aIsAbsolutelyPositioned)
aAbsoluteItems.AddChild(aNewFrame);
aAbsoluteItems.AddChild(listFrame);
listFrame = aNewFrame;
@ -2063,18 +2107,11 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContext,
// and this method initializes the ComboBox's selection state
comboBox->SetDropDown(placeholderFrame, listFrame);
// Set up the Pseudo Style contents
//XXX: What should happend if resolving the pseudo style fails?
nsCOMPtr<nsIStyleContext> visiblePseudoStyle;
aPresContext->ResolvePseudoStyleContextFor
(aContent, nsHTMLAtoms::dropDownVisible, aStyleContext, PR_FALSE,
getter_AddRefs(visiblePseudoStyle));
nsCOMPtr<nsIStyleContext> hiddenPseudoStyle;
aPresContext->ResolvePseudoStyleContextFor
(aContent, nsHTMLAtoms::dropDownHidden, aStyleContext, PR_FALSE,
getter_AddRefs(hiddenPseudoStyle));
// Set up the Pseudo Style contents for combo box button pressed and
// out.
//XXX: TODO: Make this work even if resolving the pseudo style fails.
nsCOMPtr<nsIStyleContext> outPseudoStyle;
aPresContext->ResolvePseudoStyleContextFor
(aContent, nsHTMLAtoms::dropDownBtnOut, aStyleContext, PR_FALSE,
@ -2086,22 +2123,33 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContext,
comboBox->SetDropDownStyleContexts(visiblePseudoStyle, hiddenPseudoStyle);
comboBox->SetButtonStyleContexts(outPseudoStyle, pressPseudoStyle);
nsIFrame* frame = nsnull;
if (NS_OK == comboboxFrame->QueryInterface(kIFrameIID, (void**)&frame)) {
nsFrameItems childItems;
frame->SetInitialChildList(*aPresContext, nsnull,
childItems.childList);
}
aProcessChildren = PR_FALSE;
nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, listFrame,
aStyleContext, PR_TRUE);
//XXX: TODO: Need to set an option on the view that was created for the dropdown list
//to be a borderless top-level window.
aNewFrame = comboboxFrame;
}
}
aFrameHasBeenInitialized = PR_TRUE;
}
} else {
// Construct a frame-based list box
nsIFrame * listFrame;
rv = NS_NewListControlFrame(listFrame);
aNewFrame = listFrame;
InitializeScrollFrame(listFrame, aPresContext, aContent, aParentFrame, aStyleContext,
aAbsoluteItems, aNewFrame, aFixedItems, aIsAbsolutelyPositioned, PR_FALSE, PR_TRUE);
// Set flag so the events go to the listFrame not child frames.
// Set flag so the events go to the listFrame not child frames.
// XXX: We should replace this with a real widget manager similar
// to how the nsFormControlFrame works.
// Re-directing events is a temporary Kludge.
nsIView *listView;
listFrame->GetView(&listView);
NS_ASSERTION(nsnull != listView,"ListFrame's view is nsnull");
@ -2114,7 +2162,7 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContext,
}
}
else {
// Not frame based. Use a frame which creates a native widget instead.
// Not frame based. Use a SelectFrame which creates a native widget.
rv = NS_NewSelectControlFrame(aNewFrame);
}
@ -2208,7 +2256,7 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext,
newFrame, processChildren,
isAbsolutelyPositioned,
frameHasBeenInitialized,
isFixedPositioned, aFixedItems);
isFixedPositioned, aFixedItems, aFrameItems);
}
else if (nsHTMLAtoms::applet == aTag) {
isReplaced = PR_TRUE;

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

@ -332,7 +332,8 @@ protected:
PRBool aIsAbsolutelyPositioned,
PRBool & aFrameHasBeenInitialized,
PRBool aIsFixedPositioned,
nsAbsoluteItems& aFixedItems);
nsAbsoluteItems& aFixedItems,
nsFrameItems& aFrameItems);
nsresult ConstructFrameByTag(nsIPresContext* aPresContext,
nsIContent* aContent,

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

@ -46,37 +46,25 @@
#include "nsIView.h"
#include "nsIViewManager.h"
#include "nsViewsCID.h"
#include "nsIDOMElement.h"
#include "nsListControlFrame.h"
#include "nsIListControlFrame.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMHTMLSelectElement.h"
#include "nsIDOMHTMLOptionElement.h"
#include "nsIDOMHTMLCollection.h" //rods
#include "nsIDOMHTMLSelectElement.h" //rods
#include "nsIDOMHTMLOptionElement.h" //rods
static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
static NS_DEFINE_IID(kCFileWidgetCID, NS_FILEWIDGET_CID);
static NS_DEFINE_IID(kIFileWidgetIID, NS_IFILEWIDGET_IID);
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID);
static NS_DEFINE_IID(kIComboboxControlFrameIID, NS_ICOMBOBOXCONTROLFRAME_IID);
static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID);
static NS_DEFINE_IID(kIListControlFrameIID, NS_ILISTCONTROLFRAME_IID);
static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID);
// XXX make this pixels
#define CONTROL_SPACING 40
static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
static NS_DEFINE_IID(kCFileWidgetCID, NS_FILEWIDGET_CID);
static NS_DEFINE_IID(kIFileWidgetIID, NS_IFILEWIDGET_IID);
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID);
static NS_DEFINE_IID(kIComboboxControlFrameIID, NS_ICOMBOBOXCONTROLFRAME_IID);
static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID);
#ifdef PLUGGABLE_EVENTS
static NS_DEFINE_IID(kIPluggableEventListenerIID, NS_IPLUGGABLEEVENTLISTENER_IID);
#endif
static NS_DEFINE_IID(kIListControlFrameIID, NS_ILISTCONTROLFRAME_IID);
static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID);
extern nsresult NS_NewListControlFrame(nsIFrame*& aNewFrame);
//--------------------------------------------------------------
nsresult
NS_NewComboboxControlFrame(nsIFrame*& aResult)
{
@ -87,19 +75,17 @@ NS_NewComboboxControlFrame(nsIFrame*& aResult)
return NS_OK;
}
//--------------------------------------------------------------
nsComboboxControlFrame::nsComboboxControlFrame()
: nsHTMLContainerFrame()
{
mFormFrame = nsnull;
mListFrame = nsnull;
mListControlFrame = nsnull;
mPlaceHolderFrame = nsnull;
mVisibleStyleContext = nsnull;
mHiddenStyleContext = nsnull;
mCurrentStyleContext = nsnull;
mBlockTextStyle = nsnull;
mFormFrame = nsnull;
mListFrame = nsnull;
mListControlFrame = nsnull;
mPlaceHolderFrame = nsnull;
mVisibleStyleContext = nsnull;
mHiddenStyleContext = nsnull;
mCurrentStyleContext = nsnull;
mBlockTextStyle = nsnull;
mBlockTextSelectedStyle = nsnull;
mBlockTextSelectedFocusStyle = nsnull;
mFirstTime = PR_TRUE;
@ -109,14 +95,9 @@ nsComboboxControlFrame::nsComboboxControlFrame()
//--------------------------------------------------------------
nsComboboxControlFrame::~nsComboboxControlFrame()
{
NS_IF_RELEASE(mVisibleStyleContext);
NS_IF_RELEASE(mHiddenStyleContext);
NS_IF_RELEASE(mBlockTextStyle);
//NS_IF_RELEASE(mListControlFrame);
//NS_IF_RELEASE(mListFrame);
//NS_IF_RELEASE(mPlaceHolderFrame);
}
//--------------------------------------------------------------
@ -135,13 +116,7 @@ nsComboboxControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
*aInstancePtr = (void*) ((nsIFormControlFrame*) this);
return NS_OK;
}
#ifdef PLUGGABLE_EVENTS
if (aIID.Equals(kIPluggableEventListenerIID)) {
NS_ADDREF_THIS(); // Increase reference count for caller
*aInstancePtr = (void *)((nsIPluggableEventListener*)this);
return NS_OK;
}
#endif
return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
}
@ -154,12 +129,27 @@ nsComboboxControlFrame::IsSuccessful(nsIFormControlFrame* aSubmitter)
}
//--------------------------------------------------------------
void
nsComboboxControlFrame::Reset()
{
SetFocus(PR_TRUE, PR_TRUE);
nsIFormControlFrame* fcFrame = nsnull;
nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
if ((NS_OK == result) && (nsnull != fcFrame)) {
fcFrame->Reset();
}
}
void
nsComboboxControlFrame::PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight)
{
Reset();
}
//--------------------------------------------------------------
NS_IMETHODIMP
nsComboboxControlFrame::GetType(PRInt32* aType) const
@ -173,7 +163,7 @@ NS_IMETHODIMP
nsComboboxControlFrame::GetFormContent(nsIContent*& aContent) const
{
nsIContent* content;
nsresult rv;
nsresult rv;
rv = GetContent(&content);
aContent = content;
return rv;
@ -223,28 +213,12 @@ nsComboboxControlFrame::GetHorizontalInsidePadding(nsIPresContext& aPresContext,
return 0;
}
//--------------------------------------------------------------
// XXX this should be removed when nsView exposes it
nsIWidget*
nsComboboxControlFrame::GetWindowTemp(nsIView *aView)
{
nsIWidget *window = nsnull;
nsIView *ancestor = aView;
while (nsnull != ancestor) {
ancestor->GetWidget(window);
if (nsnull != window) {
return window;
}
ancestor->GetParent(ancestor);
}
return nsnull;
}
//--------------------------------------------------------------
void
nsComboboxControlFrame::SetFocus(PRBool aOn, PRBool aRepaint)
{
//XXX: TODO Make set focus work
//mContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::kClass, "SELECTED", PR_TRUE);
mGotFocus = aOn;
if (aRepaint) {
@ -252,31 +226,48 @@ nsComboboxControlFrame::SetFocus(PRBool aOn, PRBool aRepaint)
}
}
//--------------------------------------------------------------
// this is in response to the MouseClick from the containing browse button
// XXX still need to get filters from accept attribute
// XXX: TODO still need to get filters from accept attribute
void nsComboboxControlFrame::MouseClicked(nsIPresContext* aPresContext)
{
if (nsnull != mListControlFrame) {
SetFocus(PR_FALSE, PR_TRUE);
//XXX: Make this work SetFocus(PR_FALSE, PR_TRUE);
mCurrentStyleContext = (mCurrentStyleContext == mHiddenStyleContext ? mVisibleStyleContext : mHiddenStyleContext);
if (mCurrentStyleContext == mVisibleStyleContext) {
mListControlFrame->AboutToDropDown();
nsIFormControlFrame* fcFrame = nsnull;
nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
if ((NS_OK == result) && (nsnull != fcFrame)) {
fcFrame->SetFocus(PR_TRUE, PR_FALSE);
//XXX: Make this work fcFrame->SetFocus(PR_TRUE, PR_FALSE);
}
} else {
SetFocus(PR_TRUE, PR_TRUE);
//XXX: Make this work SetFocus(PR_TRUE, PR_TRUE);
}
//XXX: This should not be necessary. Need to restructure the combo box as follows:
// Derive nsComboboxFrame from nsAreaFrame. Attach the placeholder frame, a label frame and
// a button frame. Override reresolve style context and reresolve the style on the ListBox.
// The event state manager should then be asked to set active and non-active based on
// The mouse click this would get rid of all of the ugly code here. The setting of the active
// Should cause re-resolution of the AreaFrame which will re-sync it. KMM.
mListFrame->ReResolveStyleContext(aPresContext, mCurrentStyleContext, NS_STYLE_HINT_NONE, nsnull, nsnull);
nsFormControlHelper::ForceDrawFrame(mListFrame);
// Resync view with frame.
const nsStyleDisplay* disp = (const
nsStyleDisplay*)mCurrentStyleContext->GetStyleData(eStyleStruct_Display);
nsIView * view;
mListFrame->GetView(&view);
if (view) {
view->SetVisibility(NS_STYLE_VISIBILITY_HIDDEN == disp->mVisible ?
nsViewVisibility_kHide:nsViewVisibility_kShow);
}
nsFormControlHelper::ForceDrawFrame(mListFrame);
//XXX: End of the ugly code.
}
}
//----------------------------------------------------------------------
@ -296,6 +287,9 @@ NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresConte
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
// XXX Combo box should be changed to be implemented as a label and button frame.
// This would eliminate all of this Reflow code. KMM
if (mFirstTime) {
ReResolveStyleContext(&aPresContext, mStyleContext, NS_STYLE_HINT_REFLOW, nsnull, nsnull); // XXX This temporary
mListFrame->ReResolveStyleContext(&aPresContext, mCurrentStyleContext, NS_STYLE_HINT_REFLOW, nsnull, nsnull);
@ -304,7 +298,6 @@ NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresConte
PRInt32 numChildren = mFrames.GetLength();
//nsIFrame* childFrame;
if (1 == numChildren) {
nsIAtom * textBlockContentPseudo = NS_NewAtom(":combobox-text");
aPresContext.ResolvePseudoStyleContextFor(mContent, textBlockContentPseudo,
@ -316,12 +309,8 @@ NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresConte
// changes are all done and Init() is always getting called...
/*PRBool disabled = */nsFormFrame::GetDisabled(this);
}
// nsSize maxSize(aReflowState.availableWidth, aReflowState.availableHeight);
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
{
nsIDOMHTMLSelectElement* select = nsListControlFrame::GetSelect(mContent);
nsIDOMHTMLSelectElement* select = nsListControlFrame::GetSelect(mContent);
if (!select) {
return NS_OK;
}
@ -342,7 +331,6 @@ NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresConte
for (PRUint32 i = 0; i < numOptions; i++) {
nsIDOMHTMLOptionElement* option = nsListControlFrame::GetOption(*options, i);
if (option) {
//option->CompressContent();
nsAutoString text;
if (NS_CONTENT_ATTR_HAS_VALUE != option->GetText(text)) {
continue;
@ -350,7 +338,6 @@ NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresConte
nsSize textSize;
// use the style for the select rather that the option, since widgets don't support it
nsFormControlHelper::GetTextSize(aPresContext, this, text, textSize, aReflowState.rendContext);
//nsFormControlHelper::GetTextSize(aPresContext, this, 1, textSize, aReflowState.rendContext);
if (textSize.width > maxWidth) {
maxWidth = textSize.width;
}
@ -373,22 +360,12 @@ NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresConte
float sp2t;
float p2t;
aPresContext.GetPixelsToTwips(&p2t);
aPresContext.GetScaledPixelsToTwips(&sp2t);
nscoord onePixel = NSIntPixelsToTwips(1, sp2t);
#if 0
nscoord scrollbarWidth = 0;
nscoord scrollbarHeight = 0;
nsListControlFrame::GetScrollBarDimensions(aPresContext, scrollbarWidth, scrollbarHeight);
#endif
nscoord extra = desiredSize.height - (rowHeight * numRows);
numRows = (numOptions > 20 ? 20 : numOptions);
desiredSize.height = (numRows * rowHeight) + extra;
aDesiredSize.descent = 0;
nsMargin border;
const nsStyleSpacing* mySpacing = (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
mySpacing->CalcBorderFor(this, border);
@ -401,13 +378,14 @@ NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresConte
context->GetCanonicalPixelScale(scale);
context->GetScrollBarDimensions(sbWidth, sbHeight);
PRInt32 scrollbarScaledWidth = PRInt32(sbWidth * scale);
// PRInt32 scrollbarScaledHeight = PRInt32(sbWidth * scale);
nsFont font(aPresContext.GetDefaultFixedFontDeprecated());
SystemAttrStruct sis;
sis.mFont = &font;
context->GetSystemAttribute(eSystemAttr_Font_Tooltips, &sis);
//XXX: This 14 pixel hardcode value here is bad. The style system should control
//everyting. KMM
nscoord horKludgeAdjustment = NSIntPixelsToTwips(14, p2t);
nscoord horAdjustment = scrollbarScaledWidth + border.left + border.right + horKludgeAdjustment;
@ -419,28 +397,25 @@ NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresConte
aDesiredSize.height = rowHeight + verAdjustment;
mButtonRect.SetRect(aDesiredSize.width-scrollbarScaledWidth-border.right, border.top,
scrollbarScaledWidth, aDesiredSize.height);
scrollbarScaledWidth, aDesiredSize.height - verAdjustment);
if (nsnull != aDesiredSize.maxElementSize) {
aDesiredSize.maxElementSize->width = minSize.width + verAdjustment;
aDesiredSize.maxElementSize->height = minSize.height + horAdjustment;
}
nsRect frameRect;
GetRect(frameRect);
nsRect curRect;
mPlaceHolderFrame->GetRect(curRect);
curRect.x = frameRect.x;
curRect.x = 0;
curRect.y = frameRect.y + aDesiredSize.height;
mPlaceHolderFrame->SetRect(curRect);
mListFrame->GetRect(frameRect);
}
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
@ -453,13 +428,14 @@ nsComboboxControlFrame::PaintComboboxControl(nsIPresContext& aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
//XXX Combo box should be changed to be implemented as a label and button frame.
//This would eliminate all of this rendering code. KMM
const nsStyleDisplay* disp = (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);
if (!disp->mVisible) {
return;
}
aRenderingContext.PushState();
const nsStyleColor* myColor = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);
const nsStyleSpacing* mySpacing = (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
const nsStyleFont* myFont = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
@ -538,26 +514,16 @@ nsComboboxControlFrame::PaintComboboxControl(nsIPresContext& aPresContext,
aRenderingContext.PopState(clipEmpty);
////////////////////////////////
inside.width -= scrollbarScaledWidth;
inside.height -= scrollbarScaledHeight;
inside.width -= scrollbarScaledWidth;
inside.height -= scrollbarScaledHeight;
// Scrollbars
//const nsStyleColor* myColor = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);
//nsIAtom * sbAtom = NS_NewAtom(":scrollbar-arrow-look");
//nsIStyleContext* arrowStyle = aPresContext.ResolvePseudoStyleContextFor(mContent, sbAtom, mStyleContext);
//NS_RELEASE(sbAtom);
const nsStyleSpacing* arrowSpacing = (const nsStyleSpacing*)mArrowStyle->GetStyleData(eStyleStruct_Spacing);
// const nsStyleColor* arrowColor = (const nsStyleColor*)mArrowStyle->GetStyleData(eStyleStruct_Color);
nsRect srect(0,0,0,0);//mRect.width-scrollbarWidth-onePixel, onePixel, scrollbarWidth, mRect.height-(onePixel*2));
srect = mButtonRect;
nsFormControlHelper::PaintArrow(nsFormControlHelper::eArrowDirection_Down, aRenderingContext,aPresContext,
aDirtyRect, srect, onePixel, mArrowStyle, *arrowSpacing, this, mRect);
//}
const nsStyleSpacing* arrowSpacing = (const nsStyleSpacing*)mArrowStyle->GetStyleData(eStyleStruct_Spacing);
nsRect srect(0,0,0,0);
srect = mButtonRect;
nsFormControlHelper::PaintArrow(nsFormControlHelper::eArrowDirection_Down, aRenderingContext,aPresContext,
aDirtyRect, srect, onePixel, mArrowStyle, *arrowSpacing, this, mRect);
NS_RELEASE(context);
@ -627,18 +593,9 @@ nsComboboxControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValue
// use our name and the text widgets value
aNames[0] = name;
nsresult status = PR_FALSE;
/*nsIWidget* widget;
nsITextWidget* textWidget;
mTextFrame->GetWidget(&widget);
if (widget && (NS_OK == widget->QueryInterface(kITextWidgetIID, (void**)&textWidget))) {
PRUint32 actualSize;
textWidget->GetText(aValues[0], 0, actualSize);
aNumValues = 1;
NS_RELEASE(textWidget);
status = PR_TRUE;
}
NS_IF_RELEASE(widget);*/
aValues[0] = mTextStr;
aNumValues = 1;
nsresult status = PR_TRUE;
return status;
}
@ -679,11 +636,12 @@ nsComboboxControlFrame::ReResolveStyleContext(nsIPresContext* aPresContext,
nsStyleChangeList* aChangeList,
PRInt32* aLocalChange)
{
// NOTE: using nsFrame's ReResolveStyleContext method to avoid
// useless version in base classes.
PRInt32 ourChange = aParentChange;
nsresult rv = nsHTMLContainerFrame::ReResolveStyleContext(aPresContext, aParentContext,
ourChange, aChangeList, &ourChange);
ourChange, aChangeList, &ourChange);
if (NS_FAILED(rv)) {
return rv;
}
@ -709,6 +667,10 @@ nsComboboxControlFrame::ReResolveStyleContext(nsIPresContext* aPresContext,
RefreshStyleContext(aPresContext, nsHTMLAtoms::dropDownBtnOut, mBtnOutStyleContext, mContent, mStyleContext);
RefreshStyleContext(aPresContext, nsHTMLAtoms::dropDownBtnPressed, mBtnPressedStyleContext, mContent, mStyleContext);
//Need to reset the mArrowStyle here, otherwise it might end up pointing
//to memory that has been freed, by the RefreshStyleContext above.
mArrowStyle = mBtnOutStyleContext;
nsIAtom * txtBlkContentPseudo = NS_NewAtom(":combobox-text");
RefreshStyleContext(aPresContext, txtBlkContentPseudo, mBlockTextStyle, mContent, mStyleContext);
NS_IF_RELEASE(txtBlkContentPseudo);
@ -725,14 +687,17 @@ nsComboboxControlFrame::ReResolveStyleContext(nsIPresContext* aPresContext,
}
return rv;
}
//----------------------------------------------------------------------
NS_IMETHODIMP nsComboboxControlFrame::HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
if (nsEventStatus_eConsumeNoDefault == aEventStatus) {
return NS_OK;
}
if(nsEventStatus_eConsumeNoDefault != aEventStatus) {
@ -767,56 +732,15 @@ NS_IMETHODIMP nsComboboxControlFrame::HandleEvent(nsIPresContext& aPresContext,
NS_IMETHODIMP
nsComboboxControlFrame::GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame)
{
//nsresult rv = nsScrollFrame::GetFrameForPoint(aPoint, aFrame);
nsresult rv = GetFrameForPointUsing(aPoint, nsnull, aFrame);
if (NS_OK == rv) {
if (*aFrame != this) {
//mHitFrame = *aFrame;
*aFrame = this;
}
return NS_OK;
}
*aFrame = this;
return NS_OK;
}
nsresult
nsComboboxControlFrame::GetFrameForPointUsing(const nsPoint& aPoint,
nsIAtom* aList,
nsIFrame** aFrame)
{
*aFrame = this;
return NS_OK;
}
//----------------------------------------------------------------------
// nsIPluggableEventListener
//----------------------------------------------------------------------
//----------------------------------------------------------------------
NS_IMETHODIMP nsComboboxControlFrame::PluggableEventHandler(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
HandleEvent(aPresContext, aEvent, aEventStatus);
//aEventStatus = nsEventStatus_eConsumeNoDefault;
return NS_OK;
}
//----------------------------------------------------------------------
NS_IMETHODIMP nsComboboxControlFrame::PluggableGetFrameForPoint(const nsPoint& aPoint,
nsIFrame** aFrame)
{
return GetFrameForPoint(aPoint, aFrame);
}
//----------------------------------------------------------------------
// nsIComboboxControlFrame
//----------------------------------------------------------------------
//----------------------------------------------------------------------
NS_IMETHODIMP
nsComboboxControlFrame::SetDropDown(nsIFrame* aPlaceHolderFrame, nsIFrame* aDropDownFrame)
{
@ -831,10 +755,10 @@ nsComboboxControlFrame::SetDropDown(nsIFrame* aPlaceHolderFrame, nsIFrame* aDrop
// Let's get the currently selected item, but we make the call using the Interface
mListControlFrame->GetSelectedItem(mTextStr);
AppendChildren(mPlaceHolderFrame, PR_FALSE);
return NS_OK;
}
//--------------------------------------------------------------
NS_IMETHODIMP
nsComboboxControlFrame::SetDropDownStyleContexts(nsIStyleContext * aVisible, nsIStyleContext * aHidden)
@ -879,19 +803,9 @@ nsComboboxControlFrame::ListWasSelected(nsIPresContext* aPresContext)
SetFocus(PR_TRUE, PR_TRUE);
}
return NS_OK;
}
NS_IMETHODIMP nsComboboxControlFrame::SetProperty(nsIAtom* aName, const nsString& aValue)
{
return NS_OK;
}
NS_IMETHODIMP nsComboboxControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
return NS_OK;
}
nsresult nsComboboxControlFrame::RequiresWidget(PRBool& aRequiresWidget)
{
@ -900,3 +814,23 @@ nsresult nsComboboxControlFrame::RequiresWidget(PRBool& aRequiresWidget)
}
NS_IMETHODIMP nsComboboxControlFrame::SetProperty(nsIAtom* aName, const nsString& aValue)
{
nsIFormControlFrame* fcFrame = nsnull;
nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
if ((NS_SUCCEEDED(result)) && (nsnull != fcFrame)) {
return fcFrame->SetProperty(aName, aValue);
}
return result;
}
NS_IMETHODIMP nsComboboxControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
nsIFormControlFrame* fcFrame = nsnull;
nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
if ((NS_SUCCEEDED(result)) && (nsnull != fcFrame)) {
return fcFrame->GetProperty(aName, aValue);
}
return result;
}

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

@ -19,12 +19,11 @@
#ifndef nsComboboxControlFrame_h___
#define nsComboboxControlFrame_h___
#include "nsHTMLContainerFrame.h"
#include "nsIFormControlFrame.h"
#include "nsIComboboxControlFrame.h"
#ifdef PLUGGABLE_EVENTS
#include "nsIPluggableEventListener.h"
#endif
class nsButtonControlFrame;
class nsTextControlFrame;
@ -37,9 +36,7 @@ class nsIListControlFrame;
class nsComboboxControlFrame : public nsHTMLContainerFrame,
public nsIFormControlFrame,
public nsIComboboxControlFrame
#ifdef PLUGGABLE_EVENTS
public nsIPluggableEventListener
#endif
{
public:
nsComboboxControlFrame();
@ -84,6 +81,9 @@ public:
// nsIFormControLFrame
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
virtual void PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight);
//nsTextControlFrame* GetTextFrame() { return mTextFrame; }
@ -117,9 +117,6 @@ public:
NS_IMETHOD GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame);
nsresult GetFrameForPointUsing(const nsPoint& aPoint,
nsIAtom* aList,
nsIFrame** aFrame);
// A Static Helper Functions
// This refreshes a particular pseudo style content when a "ReResolveStyleContent" happens
@ -132,16 +129,6 @@ public:
// nsIFormMouseListener
virtual void MouseClicked(nsIPresContext* aPresContext);
// nsIPluggableEventListener
NS_IMETHOD PluggableEventHandler(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
NS_IMETHOD PluggableGetFrameForPoint(const nsPoint& aPoint,
nsIFrame** aFrame);
//static PRInt32 gSpacing;
//nsIComboboxControlFrame
NS_IMETHOD SetDropDown(nsIFrame* aPlaceHolderFrame, nsIFrame* aDropDownFrame);
NS_IMETHOD SetDropDownStyleContexts(nsIStyleContext * aVisible, nsIStyleContext * aHidden);
@ -154,17 +141,14 @@ protected:
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
nsIWidget* GetWindowTemp(nsIView *aView); // XXX temporary
virtual PRIntn GetSkipSides() const;
nsFormFrame* mFormFrame; // Parent Form Frame
nsIFrame * mPlaceHolderFrame;
nsIFrame * mListFrame; // Generic nsIFrame
nsIListControlFrame * mListControlFrame; // Specific ListControl Interface
nsRect mButtonRect; // The Arrow Button's Rect cached for Painting
// DropDown List Visibility Styles
nsIStyleContext * mVisibleStyleContext; // Style for the DropDown List to make it visible
nsIStyleContext * mHiddenStyleContext; // Style for the DropDown List to make it hidden
@ -180,7 +164,6 @@ protected:
nsIStyleContext * mBlockTextSelectedStyle; // Style when selected and it doesn't have focus
nsIStyleContext * mBlockTextSelectedFocusStyle; // Style when selected and it has focus
PRBool mFirstTime;
// State data members

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

@ -64,13 +64,13 @@
#include "nsFormFrame.h"
#include "nsIScrollableView.h"
#define CSS_NOTSET -1
#define ATTR_NOTSET -1
// Constants
const char * kNormal = "";
const char * kSelected = "SELECTED";
const char * kSelectedFocus = "SELECTEDFOCUS";
//XXX: This is temporary. It simulates psuedo states by using a attribute selector on
// -moz-option-selected in the ua.css style sheet. This will not be needed when
//The event state manager is functional. KMM
const char * kMozSelected = "-moz-option-selected";
static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID);
@ -116,7 +116,6 @@ nsListControlFrame::~nsListControlFrame()
NS_IF_RELEASE(mComboboxFrame);
}
//----------------------------------------------------------------------
NS_IMPL_ADDREF(nsListControlFrame)
NS_IMPL_RELEASE(nsListControlFrame)
@ -146,6 +145,11 @@ nsListControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
NS_IMETHODIMP
nsListControlFrame::GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame)
{
// Save the result of GetFrameForPointUsing in the mHitFrame member variable.
// mHitFrame is used later in the HandleLikeListEvent to determine what was clicked on.
// XXX: This is kludgy, but there doesn't seem to be a way to get what was just clicked
// on in the HandleEvent. The GetFrameForPointUsing is always called before the HandleEvent.
//
nsresult rv;
nsIFrame *childFrame;
@ -178,9 +182,14 @@ nsListControlFrame::GetFrameForPointUsing(const nsPoint& aPoint,
nsIFrame* firstKid = nsnull;
// XXX:Hack. This should not be necessary.
// Get the scrolled offset from the view.
//
// XXX:Hack. This should not be necessary. It is only required because we interpose on the
// normal event flow by redirecting to the listbox using the SetVFlags(NS_DONT_CHECK_CHILDREN).
// What we should really do is have a manager which the option items report there events to.
// The listbox frame would be the manager for the option items. KMM.
//
//
// This is needed because:
// The scrolled view is below the nsListControlFrame's ScrollingView in
// the view hierarchy. This presents a problem for event translation when the events
@ -227,8 +236,6 @@ nsListControlFrame::GetFrameForPointUsing(const nsPoint& aPoint,
}
NS_RELEASE(content);
return kid->GetFrameForPoint(tmp, aFrame);
//*aFrame = kid;
//return NS_OK;
}
kid->GetNextSibling(&kid);
}
@ -286,7 +293,11 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
nsIFrame* childFrame = nsnull;
mContentFrame->FirstChild(nsnull, &childFrame);
PRInt32 numChildren = LengthOf(childFrame);
PRBool needsVerticalScrollbar = (numChildren > mNumRows);
PRBool needsVerticalScrollbar = PR_FALSE;
if (PR_FALSE == mInDropDownMode) {
PRBool needsVerticalScrollbar = (numChildren > mNumRows);
}
//--Calculate a width just big enough for the scrollframe to shrink around the
//longest element in the list
@ -306,14 +317,12 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
// XXX: This should be changed to do the inherited reflow unconstrained for
// the width to get the real desired width. GetDesiredSize is limited to
// text strings.
//XXX: TODO: Use the width and height of an the first reflow to determine how high and wide
//to make the listbox, instead of calculating it. The second reflow can be done actually position
//the frames correctly using: tempReflowState.reason = eReflowReason_Resize;
GetDesiredSize(&aPresContext, aReflowState, desiredSize, desiredLineSize);
// Only set to the desired width if it hasn't been explicitly defined through CSS.
// GetDesiredSize must still be done above to calculate the desired height.
if (NS_UNCONSTRAINEDSIZE == tempReflowState.computedWidth) {
tempReflowState.computedWidth = desiredLineSize.width;
}
// Retrieve the scrollbar's width and height
float sbWidth = 0.0;
float sbHeight = 0.0;;
@ -324,6 +333,16 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
nscoord scrollbarWidth = NSToCoordRound(sbWidth);
nscoord scrollbarHeight = NSToCoordRound(sbHeight);
if (mInDropDownMode) {
// For drop-down lists, always size the width of the list based on
// the desired lineSize.
tempReflowState.computedWidth = desiredLineSize.width + scrollbarWidth;
} else if (NS_UNCONSTRAINEDSIZE == tempReflowState.computedWidth) {
// Only set to the desired width if it hasn't been explicitly defined through CSS.
// GetDesiredSize must still be done above to calculate the desired height.
tempReflowState.computedWidth = desiredLineSize.width;
}
// Add vertical scrollbar, Always add it in,
// even though the vertical scrollbar is not needed all the time
// the inherited Reflow: allways leave space for the scrollbar by
@ -333,10 +352,8 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
// Now that we have calculated the width required to just shrink around the longest line.
// Go ahead and reflow
// Do the inherited Reflow. This reflow uses the computed widths which
// are setup above.
// Don't set the height. Let the height be unconstrained
nsScrollFrame::Reflow(aPresContext,
@ -368,12 +385,13 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
aDesiredSize.maxElementSize->height = aDesiredSize.height;
}
//XXX: Set the min element size here to the desired element size here??
// XXX: Set the min element size here to the desired element size here??
// Restore to original reflow state.
tempReflowState.computedWidth = saveComputedWidth;
tempReflowState.availableWidth = saveAvailableWidth;
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
}
@ -443,12 +461,18 @@ nsListControlFrame::GetFont(nsIPresContext* aPresContext,
void nsListControlFrame::DisplaySelected(nsIContent* aContent)
{
//XXX: This is temporary. It simulates psuedo states by using a attribute selector on
// -moz-option-selected in the ua.css style sheet. This will not be needed when
// The event state manager is functional. KMM
nsCOMPtr<nsIAtom> selectedAtom ( dont_QueryInterface(NS_NewAtom(kMozSelected)));
aContent->SetAttribute(kNameSpaceID_None, selectedAtom, "", PR_TRUE);
}
void nsListControlFrame::DisplayDeselected(nsIContent* aContent)
{
//XXX: This is temporary. It simulates psuedo states by using a attribute selector on
// -moz-option-selected in the ua.css style sheet. This will not be needed when
// The event state manager is functional. KMM
nsCOMPtr<nsIAtom> selectedAtom ( dont_QueryInterface(NS_NewAtom(kMozSelected)));
aContent->UnsetAttribute(kNameSpaceID_None, selectedAtom, PR_TRUE);
}
@ -465,7 +489,7 @@ void nsListControlFrame::UpdateItem(nsIContent* aContent, PRBool aSelected)
//----------------------------------------------------------------------
PRInt32 nsListControlFrame::SetContentSelected(nsIFrame * aHitFrame,
nsIContent *& aHitContent,
PRBool aIsSelected)
PRBool aDisplaySelected)
{
PRInt32 index = 0;
nsIFrame* kid;
@ -476,7 +500,8 @@ PRInt32 nsListControlFrame::SetContentSelected(nsIFrame * aHitFrame,
nsIContent* content;
kid->GetContent(&content);
aHitContent = content;
//XXX: DisplaySelected(aHitContent);
if (PR_TRUE == aDisplaySelected)
DisplaySelected(aHitContent);
return index;
}
kid->GetNextSibling(&kid);
@ -557,7 +582,7 @@ NS_IMETHODIMP nsListControlFrame::HandleLikeListEvent(nsIPresContext& aPresConte
if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN) {
PRInt32 oldSelectedIndex = mSelectedIndex;
mSelectedIndex = (PRInt32)SetContentSelected(mHitFrame, mHitContent, PR_TRUE);
mSelectedIndex = (PRInt32)SetContentSelected(mHitFrame, mHitContent, PR_FALSE);
if (-1 < mSelectedIndex) {
PRBool wasSelected = IsFrameSelected(mSelectedIndex);
SetFrameSelected(mSelectedIndex, PR_TRUE);
@ -663,13 +688,12 @@ NS_IMETHODIMP nsListControlFrame::HandleLikeDropDownListEvent(nsIPresContext& aP
// Now cache the the newly hit frame and content as the "current" values
mCurrentHitFrame = mHitFrame;
mCurrentHitContent = mHitContent;
}
} else if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) {
// Start by finding the newly "hit" content from the hit frame
PRInt32 index = SetContentSelected(mHitFrame, mHitContent, PR_FALSE);
PRInt32 index = SetContentSelected(mHitFrame, mHitContent, PR_TRUE);
if (-1 < index) {
nsIDOMHTMLOptionElement* option = nsnull;
@ -905,7 +929,6 @@ nsListControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
for (PRUint32 i = 0; i < numOptions; i++) {
nsIDOMHTMLOptionElement* option = GetOption(*options, i);
if (option) {
//option->CompressContent();
nsAutoString text;
if (NS_CONTENT_ATTR_HAS_VALUE != option->GetText(text)) {
continue;
@ -936,28 +959,14 @@ nsListControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
aPresContext->GetPixelsToTwips(&p2t);
aPresContext->GetScaledPixelsToTwips(&sp2t);
//nscoord scrollbarWidth = 0;
//nscoord scrollbarHeight = 0;
//GetScrollBarDimensions(*aPresContext, scrollbarWidth, scrollbarHeight);
if (mInDropDownMode) {
//PRUint32 numOptions;
//options->GetLength(&numOptions);
nscoord extra = desiredSize.height - (rowHeight * mNumRows);
mNumRows = (numOptions > 20 ? 20 : numOptions);
desiredSize.height = (mNumRows * rowHeight) + extra;
if (mNumRows < 21) {
//calcSize.width += scrollbarWidth;
}
}
aDesiredLayoutSize.width = desiredSize.width;
// account for vertical scrollbar, if present
//if (!widthExplicit && ((mNumRows < numOptions) || mIsComboBox)) {
//if (!widthExplicit && (mNumRows < (PRInt32)numOptions)) {
// aDesiredLayoutSize.width += scrollbarWidth;
// }
// XXX put this in widget library, combo boxes are fixed height (visible part)
//aDesiredLayoutSize.height = (mIsComboBox)
@ -972,18 +981,7 @@ nsListControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
aDesiredWidgetSize.width = maxWidth;
aDesiredWidgetSize.height = rowHeight;
//if (mIsComboBox) { // add in pull down size
// PRInt32 extra = NSIntPixelsToTwips(10, p2t*scale);
// 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;
//}
if (aDesiredLayoutSize.maxElementSize) {
aDesiredLayoutSize.maxElementSize->width = minSize.width;
aDesiredLayoutSize.maxElementSize->height = minSize.height;
@ -1394,6 +1392,7 @@ nsListControlFrame::SetFocus(PRBool aOn, PRBool aRepaint)
// XXX I don't know whether to use the aRepaint flag as last param
// in this call?
if (mSelectedContent) {
//XXX: Need correct attribute here
mSelectedContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::kClass, (aOn?kSelectedFocus:kNormal), PR_TRUE);
}
@ -1420,16 +1419,6 @@ nsListControlFrame::GetSelectedItem(nsString & aStr)
return NS_OK;
}
NS_IMETHODIMP nsListControlFrame::SetProperty(nsIAtom* aName, const nsString& aValue)
{
return NS_OK;
}
NS_IMETHODIMP nsListControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
return NS_OK;
}
nsresult nsListControlFrame::RequiresWidget(PRBool& aRequiresWidget)
{
aRequiresWidget = PR_FALSE;
@ -1437,4 +1426,72 @@ nsresult nsListControlFrame::RequiresWidget(PRBool& aRequiresWidget)
}
PRInt32 nsListControlFrame::GetNumberOfOptions()
{
nsIDOMHTMLCollection* options = GetOptions(mContent);
if (!options) {
return 0;
}
PRUint32 numOptions;
options->GetLength(&numOptions);
NS_RELEASE(options);
return(numOptions);
}
NS_IMETHODIMP nsListControlFrame::SetProperty(nsIAtom* aName, const nsString& aValue)
{
if (nsHTMLAtoms::selected == aName) {
return NS_ERROR_INVALID_ARG; // Selected is readonly according to spec.
} else if (nsHTMLAtoms::selectedindex == aName) {
PRInt32 error = 0;
PRInt32 selectedIndex = aValue.ToInteger(&error, 10); // Get index from aValue
if (error) {
return NS_ERROR_INVALID_ARG; // Couldn't convert to integer
} else {
SetFrameSelected(selectedIndex, PR_TRUE);
}
} else {
//XXX: TODO What about all othe other properties that form elements can set here?
// return nsFormControlFrame::SetProperty(aName, aValue);
}
return NS_OK;
}
NS_IMETHODIMP nsListControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
// Get the selected value of option from local cache (optimization vs. widget)
if (nsHTMLAtoms::selected == aName) {
PRInt32 error = 0;
PRBool selected = PR_FALSE;
PRInt32 index = aValue.ToInteger(&error, 10); // Get index from aValue
if (error == 0)
selected = IsFrameSelected(index);
nsFormControlHelper::GetBoolString(selected, aValue);
// For selectedIndex, get the value from the widget
} else if (nsHTMLAtoms::selectedindex == aName) {
// Spin through loooking for the first selection in the list
PRInt32 index = 0;
PRInt32 maxOptions = GetNumberOfOptions();
PRInt32 selectedIndex = -1;
for (index = 0; index < maxOptions; index++) {
PRBool isSelected = PR_FALSE;
if (PR_TRUE == IsFrameSelected(index)) {
selectedIndex = isSelected;
break;
}
}
aValue.Append(selectedIndex, 10);
} else {
//XXX: TODO: What about all of the other form properties???
//return nsFormControlFrame::GetProperty(aName, aValue);
}
return NS_OK;
}

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

@ -65,6 +65,7 @@ public:
NS_IMETHOD SetInitialChildList(nsIPresContext& aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList);
NS_IMETHOD Reflow(nsIPresContext& aCX,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
@ -167,6 +168,8 @@ protected:
nsListControlFrame();
virtual ~nsListControlFrame();
PRInt32 GetNumberOfOptions();
nsIFrame * GetOptionFromChild(nsIFrame* aParentFrame);
nsresult GetFrameForPointUsing(const nsPoint& aPoint,
@ -194,7 +197,7 @@ protected:
nsEventStatus& aEventStatus);
PRInt32 SetContentSelected(nsIFrame * aHitFrame,
nsIContent *& aHitContent,
PRBool aIsSelected);
PRBool aDisplaySelected);
// Data Members
nsFormFrame* mFormFrame;

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

@ -92,6 +92,7 @@ nsIAtom* nsHTMLAtoms::dropDownVisible;
nsIAtom* nsHTMLAtoms::dropDownHidden;
nsIAtom* nsHTMLAtoms::dropDownBtnOut;
nsIAtom* nsHTMLAtoms::dropDownBtnPressed;
nsIAtom* nsHTMLAtoms::dropDownList;
nsIAtom* nsHTMLAtoms::embed;
nsIAtom* nsHTMLAtoms::encoding;
nsIAtom* nsHTMLAtoms::enctype;
@ -344,10 +345,11 @@ void nsHTMLAtoms::AddrefAtoms()
div = NS_NewAtom("div");
disabled = NS_NewAtom("disabled");
dl = NS_NewAtom("dl");
dropDownVisible = NS_NewAtom(":dropdown-visible");
dropDownHidden = NS_NewAtom(":dropdown-hidden");
dropDownBtnOut = NS_NewAtom(":dropdown-btn-out");
dropDownBtnPressed = NS_NewAtom(":dropdown-btn-pressed");
dropDownVisible = NS_NewAtom(":-moz-dropdown-visible");
dropDownHidden = NS_NewAtom(":-moz-dropdown-hidden");
dropDownBtnOut = NS_NewAtom(":-moz-dropdown-btn-out");
dropDownBtnPressed = NS_NewAtom(":-moz-dropdown-btn-pressed");
dropDownList = NS_NewAtom(":-moz-dropdown-list");
datetime = NS_NewAtom("datetime");
data = NS_NewAtom("data");
embed = NS_NewAtom("embed");
@ -606,6 +608,7 @@ void nsHTMLAtoms::ReleaseAtoms()
NS_RELEASE(dropDownHidden);
NS_RELEASE(dropDownBtnOut);
NS_RELEASE(dropDownBtnPressed);
NS_RELEASE(dropDownList);
NS_RELEASE(embed);
NS_RELEASE(encoding);
NS_RELEASE(face);

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

@ -114,6 +114,7 @@ public:
static nsIAtom* dropDownHidden;
static nsIAtom* dropDownBtnOut;
static nsIAtom* dropDownBtnPressed;
static nsIAtom* dropDownList;
static nsIAtom* embed;
static nsIAtom* encoding;

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

@ -883,14 +883,33 @@ sourcetext {
display: none;
}
:dropdown-visible {
:-moz-dropdown-visible {
visibility: visible;
}
:dropdown-hidden {
:-moz-dropdown-hidden {
visibility: hidden;
}
:-moz-dropdown-btn-out {
border: 2px outset #c0c0c0;
background-color: rgb(206, 207, 206);
}
:-moz-dropdown-btn-pressed {
border: 2px inset #c0c0c0;
background-color: rgb(206, 207, 206);
}
:-moz-dropdown-list {
position:absolute;
height:200px;
width:100px;
background-color:white;
border: 1px solid blue;
}
:combobox-text {
color: black;
padding-left: 2px;

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

@ -46,37 +46,25 @@
#include "nsIView.h"
#include "nsIViewManager.h"
#include "nsViewsCID.h"
#include "nsIDOMElement.h"
#include "nsListControlFrame.h"
#include "nsIListControlFrame.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDOMHTMLSelectElement.h"
#include "nsIDOMHTMLOptionElement.h"
#include "nsIDOMHTMLCollection.h" //rods
#include "nsIDOMHTMLSelectElement.h" //rods
#include "nsIDOMHTMLOptionElement.h" //rods
static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
static NS_DEFINE_IID(kCFileWidgetCID, NS_FILEWIDGET_CID);
static NS_DEFINE_IID(kIFileWidgetIID, NS_IFILEWIDGET_IID);
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID);
static NS_DEFINE_IID(kIComboboxControlFrameIID, NS_ICOMBOBOXCONTROLFRAME_IID);
static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID);
static NS_DEFINE_IID(kIListControlFrameIID, NS_ILISTCONTROLFRAME_IID);
static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID);
// XXX make this pixels
#define CONTROL_SPACING 40
static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
static NS_DEFINE_IID(kCFileWidgetCID, NS_FILEWIDGET_CID);
static NS_DEFINE_IID(kIFileWidgetIID, NS_IFILEWIDGET_IID);
static NS_DEFINE_IID(kITextWidgetIID, NS_ITEXTWIDGET_IID);
static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID);
static NS_DEFINE_IID(kIComboboxControlFrameIID, NS_ICOMBOBOXCONTROLFRAME_IID);
static NS_DEFINE_IID(kIDOMHTMLSelectElementIID, NS_IDOMHTMLSELECTELEMENT_IID);
static NS_DEFINE_IID(kIDOMHTMLOptionElementIID, NS_IDOMHTMLOPTIONELEMENT_IID);
#ifdef PLUGGABLE_EVENTS
static NS_DEFINE_IID(kIPluggableEventListenerIID, NS_IPLUGGABLEEVENTLISTENER_IID);
#endif
static NS_DEFINE_IID(kIListControlFrameIID, NS_ILISTCONTROLFRAME_IID);
static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID);
extern nsresult NS_NewListControlFrame(nsIFrame*& aNewFrame);
//--------------------------------------------------------------
nsresult
NS_NewComboboxControlFrame(nsIFrame*& aResult)
{
@ -87,19 +75,17 @@ NS_NewComboboxControlFrame(nsIFrame*& aResult)
return NS_OK;
}
//--------------------------------------------------------------
nsComboboxControlFrame::nsComboboxControlFrame()
: nsHTMLContainerFrame()
{
mFormFrame = nsnull;
mListFrame = nsnull;
mListControlFrame = nsnull;
mPlaceHolderFrame = nsnull;
mVisibleStyleContext = nsnull;
mHiddenStyleContext = nsnull;
mCurrentStyleContext = nsnull;
mBlockTextStyle = nsnull;
mFormFrame = nsnull;
mListFrame = nsnull;
mListControlFrame = nsnull;
mPlaceHolderFrame = nsnull;
mVisibleStyleContext = nsnull;
mHiddenStyleContext = nsnull;
mCurrentStyleContext = nsnull;
mBlockTextStyle = nsnull;
mBlockTextSelectedStyle = nsnull;
mBlockTextSelectedFocusStyle = nsnull;
mFirstTime = PR_TRUE;
@ -109,14 +95,9 @@ nsComboboxControlFrame::nsComboboxControlFrame()
//--------------------------------------------------------------
nsComboboxControlFrame::~nsComboboxControlFrame()
{
NS_IF_RELEASE(mVisibleStyleContext);
NS_IF_RELEASE(mHiddenStyleContext);
NS_IF_RELEASE(mBlockTextStyle);
//NS_IF_RELEASE(mListControlFrame);
//NS_IF_RELEASE(mListFrame);
//NS_IF_RELEASE(mPlaceHolderFrame);
}
//--------------------------------------------------------------
@ -135,13 +116,7 @@ nsComboboxControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
*aInstancePtr = (void*) ((nsIFormControlFrame*) this);
return NS_OK;
}
#ifdef PLUGGABLE_EVENTS
if (aIID.Equals(kIPluggableEventListenerIID)) {
NS_ADDREF_THIS(); // Increase reference count for caller
*aInstancePtr = (void *)((nsIPluggableEventListener*)this);
return NS_OK;
}
#endif
return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr);
}
@ -154,12 +129,27 @@ nsComboboxControlFrame::IsSuccessful(nsIFormControlFrame* aSubmitter)
}
//--------------------------------------------------------------
void
nsComboboxControlFrame::Reset()
{
SetFocus(PR_TRUE, PR_TRUE);
nsIFormControlFrame* fcFrame = nsnull;
nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
if ((NS_OK == result) && (nsnull != fcFrame)) {
fcFrame->Reset();
}
}
void
nsComboboxControlFrame::PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight)
{
Reset();
}
//--------------------------------------------------------------
NS_IMETHODIMP
nsComboboxControlFrame::GetType(PRInt32* aType) const
@ -173,7 +163,7 @@ NS_IMETHODIMP
nsComboboxControlFrame::GetFormContent(nsIContent*& aContent) const
{
nsIContent* content;
nsresult rv;
nsresult rv;
rv = GetContent(&content);
aContent = content;
return rv;
@ -223,28 +213,12 @@ nsComboboxControlFrame::GetHorizontalInsidePadding(nsIPresContext& aPresContext,
return 0;
}
//--------------------------------------------------------------
// XXX this should be removed when nsView exposes it
nsIWidget*
nsComboboxControlFrame::GetWindowTemp(nsIView *aView)
{
nsIWidget *window = nsnull;
nsIView *ancestor = aView;
while (nsnull != ancestor) {
ancestor->GetWidget(window);
if (nsnull != window) {
return window;
}
ancestor->GetParent(ancestor);
}
return nsnull;
}
//--------------------------------------------------------------
void
nsComboboxControlFrame::SetFocus(PRBool aOn, PRBool aRepaint)
{
//XXX: TODO Make set focus work
//mContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::kClass, "SELECTED", PR_TRUE);
mGotFocus = aOn;
if (aRepaint) {
@ -252,31 +226,48 @@ nsComboboxControlFrame::SetFocus(PRBool aOn, PRBool aRepaint)
}
}
//--------------------------------------------------------------
// this is in response to the MouseClick from the containing browse button
// XXX still need to get filters from accept attribute
// XXX: TODO still need to get filters from accept attribute
void nsComboboxControlFrame::MouseClicked(nsIPresContext* aPresContext)
{
if (nsnull != mListControlFrame) {
SetFocus(PR_FALSE, PR_TRUE);
//XXX: Make this work SetFocus(PR_FALSE, PR_TRUE);
mCurrentStyleContext = (mCurrentStyleContext == mHiddenStyleContext ? mVisibleStyleContext : mHiddenStyleContext);
if (mCurrentStyleContext == mVisibleStyleContext) {
mListControlFrame->AboutToDropDown();
nsIFormControlFrame* fcFrame = nsnull;
nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
if ((NS_OK == result) && (nsnull != fcFrame)) {
fcFrame->SetFocus(PR_TRUE, PR_FALSE);
//XXX: Make this work fcFrame->SetFocus(PR_TRUE, PR_FALSE);
}
} else {
SetFocus(PR_TRUE, PR_TRUE);
//XXX: Make this work SetFocus(PR_TRUE, PR_TRUE);
}
//XXX: This should not be necessary. Need to restructure the combo box as follows:
// Derive nsComboboxFrame from nsAreaFrame. Attach the placeholder frame, a label frame and
// a button frame. Override reresolve style context and reresolve the style on the ListBox.
// The event state manager should then be asked to set active and non-active based on
// The mouse click this would get rid of all of the ugly code here. The setting of the active
// Should cause re-resolution of the AreaFrame which will re-sync it. KMM.
mListFrame->ReResolveStyleContext(aPresContext, mCurrentStyleContext, NS_STYLE_HINT_NONE, nsnull, nsnull);
nsFormControlHelper::ForceDrawFrame(mListFrame);
// Resync view with frame.
const nsStyleDisplay* disp = (const
nsStyleDisplay*)mCurrentStyleContext->GetStyleData(eStyleStruct_Display);
nsIView * view;
mListFrame->GetView(&view);
if (view) {
view->SetVisibility(NS_STYLE_VISIBILITY_HIDDEN == disp->mVisible ?
nsViewVisibility_kHide:nsViewVisibility_kShow);
}
nsFormControlHelper::ForceDrawFrame(mListFrame);
//XXX: End of the ugly code.
}
}
//----------------------------------------------------------------------
@ -296,6 +287,9 @@ NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresConte
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus)
{
// XXX Combo box should be changed to be implemented as a label and button frame.
// This would eliminate all of this Reflow code. KMM
if (mFirstTime) {
ReResolveStyleContext(&aPresContext, mStyleContext, NS_STYLE_HINT_REFLOW, nsnull, nsnull); // XXX This temporary
mListFrame->ReResolveStyleContext(&aPresContext, mCurrentStyleContext, NS_STYLE_HINT_REFLOW, nsnull, nsnull);
@ -304,7 +298,6 @@ NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresConte
PRInt32 numChildren = mFrames.GetLength();
//nsIFrame* childFrame;
if (1 == numChildren) {
nsIAtom * textBlockContentPseudo = NS_NewAtom(":combobox-text");
aPresContext.ResolvePseudoStyleContextFor(mContent, textBlockContentPseudo,
@ -316,12 +309,8 @@ NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresConte
// changes are all done and Init() is always getting called...
/*PRBool disabled = */nsFormFrame::GetDisabled(this);
}
// nsSize maxSize(aReflowState.availableWidth, aReflowState.availableHeight);
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
{
nsIDOMHTMLSelectElement* select = nsListControlFrame::GetSelect(mContent);
nsIDOMHTMLSelectElement* select = nsListControlFrame::GetSelect(mContent);
if (!select) {
return NS_OK;
}
@ -342,7 +331,6 @@ NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresConte
for (PRUint32 i = 0; i < numOptions; i++) {
nsIDOMHTMLOptionElement* option = nsListControlFrame::GetOption(*options, i);
if (option) {
//option->CompressContent();
nsAutoString text;
if (NS_CONTENT_ATTR_HAS_VALUE != option->GetText(text)) {
continue;
@ -350,7 +338,6 @@ NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresConte
nsSize textSize;
// use the style for the select rather that the option, since widgets don't support it
nsFormControlHelper::GetTextSize(aPresContext, this, text, textSize, aReflowState.rendContext);
//nsFormControlHelper::GetTextSize(aPresContext, this, 1, textSize, aReflowState.rendContext);
if (textSize.width > maxWidth) {
maxWidth = textSize.width;
}
@ -373,22 +360,12 @@ NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresConte
float sp2t;
float p2t;
aPresContext.GetPixelsToTwips(&p2t);
aPresContext.GetScaledPixelsToTwips(&sp2t);
nscoord onePixel = NSIntPixelsToTwips(1, sp2t);
#if 0
nscoord scrollbarWidth = 0;
nscoord scrollbarHeight = 0;
nsListControlFrame::GetScrollBarDimensions(aPresContext, scrollbarWidth, scrollbarHeight);
#endif
nscoord extra = desiredSize.height - (rowHeight * numRows);
numRows = (numOptions > 20 ? 20 : numOptions);
desiredSize.height = (numRows * rowHeight) + extra;
aDesiredSize.descent = 0;
nsMargin border;
const nsStyleSpacing* mySpacing = (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
mySpacing->CalcBorderFor(this, border);
@ -401,13 +378,14 @@ NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresConte
context->GetCanonicalPixelScale(scale);
context->GetScrollBarDimensions(sbWidth, sbHeight);
PRInt32 scrollbarScaledWidth = PRInt32(sbWidth * scale);
// PRInt32 scrollbarScaledHeight = PRInt32(sbWidth * scale);
nsFont font(aPresContext.GetDefaultFixedFontDeprecated());
SystemAttrStruct sis;
sis.mFont = &font;
context->GetSystemAttribute(eSystemAttr_Font_Tooltips, &sis);
//XXX: This 14 pixel hardcode value here is bad. The style system should control
//everyting. KMM
nscoord horKludgeAdjustment = NSIntPixelsToTwips(14, p2t);
nscoord horAdjustment = scrollbarScaledWidth + border.left + border.right + horKludgeAdjustment;
@ -419,28 +397,25 @@ NS_IMETHODIMP nsComboboxControlFrame::Reflow(nsIPresContext& aPresConte
aDesiredSize.height = rowHeight + verAdjustment;
mButtonRect.SetRect(aDesiredSize.width-scrollbarScaledWidth-border.right, border.top,
scrollbarScaledWidth, aDesiredSize.height);
scrollbarScaledWidth, aDesiredSize.height - verAdjustment);
if (nsnull != aDesiredSize.maxElementSize) {
aDesiredSize.maxElementSize->width = minSize.width + verAdjustment;
aDesiredSize.maxElementSize->height = minSize.height + horAdjustment;
}
nsRect frameRect;
GetRect(frameRect);
nsRect curRect;
mPlaceHolderFrame->GetRect(curRect);
curRect.x = frameRect.x;
curRect.x = 0;
curRect.y = frameRect.y + aDesiredSize.height;
mPlaceHolderFrame->SetRect(curRect);
mListFrame->GetRect(frameRect);
}
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
aDesiredSize.ascent = aDesiredSize.height;
aDesiredSize.descent = 0;
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
@ -453,13 +428,14 @@ nsComboboxControlFrame::PaintComboboxControl(nsIPresContext& aPresContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer)
{
//XXX Combo box should be changed to be implemented as a label and button frame.
//This would eliminate all of this rendering code. KMM
const nsStyleDisplay* disp = (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display);
if (!disp->mVisible) {
return;
}
aRenderingContext.PushState();
const nsStyleColor* myColor = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);
const nsStyleSpacing* mySpacing = (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
const nsStyleFont* myFont = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font);
@ -538,26 +514,16 @@ nsComboboxControlFrame::PaintComboboxControl(nsIPresContext& aPresContext,
aRenderingContext.PopState(clipEmpty);
////////////////////////////////
inside.width -= scrollbarScaledWidth;
inside.height -= scrollbarScaledHeight;
inside.width -= scrollbarScaledWidth;
inside.height -= scrollbarScaledHeight;
// Scrollbars
//const nsStyleColor* myColor = (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color);
//nsIAtom * sbAtom = NS_NewAtom(":scrollbar-arrow-look");
//nsIStyleContext* arrowStyle = aPresContext.ResolvePseudoStyleContextFor(mContent, sbAtom, mStyleContext);
//NS_RELEASE(sbAtom);
const nsStyleSpacing* arrowSpacing = (const nsStyleSpacing*)mArrowStyle->GetStyleData(eStyleStruct_Spacing);
// const nsStyleColor* arrowColor = (const nsStyleColor*)mArrowStyle->GetStyleData(eStyleStruct_Color);
nsRect srect(0,0,0,0);//mRect.width-scrollbarWidth-onePixel, onePixel, scrollbarWidth, mRect.height-(onePixel*2));
srect = mButtonRect;
nsFormControlHelper::PaintArrow(nsFormControlHelper::eArrowDirection_Down, aRenderingContext,aPresContext,
aDirtyRect, srect, onePixel, mArrowStyle, *arrowSpacing, this, mRect);
//}
const nsStyleSpacing* arrowSpacing = (const nsStyleSpacing*)mArrowStyle->GetStyleData(eStyleStruct_Spacing);
nsRect srect(0,0,0,0);
srect = mButtonRect;
nsFormControlHelper::PaintArrow(nsFormControlHelper::eArrowDirection_Down, aRenderingContext,aPresContext,
aDirtyRect, srect, onePixel, mArrowStyle, *arrowSpacing, this, mRect);
NS_RELEASE(context);
@ -627,18 +593,9 @@ nsComboboxControlFrame::GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValue
// use our name and the text widgets value
aNames[0] = name;
nsresult status = PR_FALSE;
/*nsIWidget* widget;
nsITextWidget* textWidget;
mTextFrame->GetWidget(&widget);
if (widget && (NS_OK == widget->QueryInterface(kITextWidgetIID, (void**)&textWidget))) {
PRUint32 actualSize;
textWidget->GetText(aValues[0], 0, actualSize);
aNumValues = 1;
NS_RELEASE(textWidget);
status = PR_TRUE;
}
NS_IF_RELEASE(widget);*/
aValues[0] = mTextStr;
aNumValues = 1;
nsresult status = PR_TRUE;
return status;
}
@ -679,11 +636,12 @@ nsComboboxControlFrame::ReResolveStyleContext(nsIPresContext* aPresContext,
nsStyleChangeList* aChangeList,
PRInt32* aLocalChange)
{
// NOTE: using nsFrame's ReResolveStyleContext method to avoid
// useless version in base classes.
PRInt32 ourChange = aParentChange;
nsresult rv = nsHTMLContainerFrame::ReResolveStyleContext(aPresContext, aParentContext,
ourChange, aChangeList, &ourChange);
ourChange, aChangeList, &ourChange);
if (NS_FAILED(rv)) {
return rv;
}
@ -709,6 +667,10 @@ nsComboboxControlFrame::ReResolveStyleContext(nsIPresContext* aPresContext,
RefreshStyleContext(aPresContext, nsHTMLAtoms::dropDownBtnOut, mBtnOutStyleContext, mContent, mStyleContext);
RefreshStyleContext(aPresContext, nsHTMLAtoms::dropDownBtnPressed, mBtnPressedStyleContext, mContent, mStyleContext);
//Need to reset the mArrowStyle here, otherwise it might end up pointing
//to memory that has been freed, by the RefreshStyleContext above.
mArrowStyle = mBtnOutStyleContext;
nsIAtom * txtBlkContentPseudo = NS_NewAtom(":combobox-text");
RefreshStyleContext(aPresContext, txtBlkContentPseudo, mBlockTextStyle, mContent, mStyleContext);
NS_IF_RELEASE(txtBlkContentPseudo);
@ -725,14 +687,17 @@ nsComboboxControlFrame::ReResolveStyleContext(nsIPresContext* aPresContext,
}
return rv;
}
//----------------------------------------------------------------------
NS_IMETHODIMP nsComboboxControlFrame::HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
if (nsEventStatus_eConsumeNoDefault == aEventStatus) {
return NS_OK;
}
if(nsEventStatus_eConsumeNoDefault != aEventStatus) {
@ -767,56 +732,15 @@ NS_IMETHODIMP nsComboboxControlFrame::HandleEvent(nsIPresContext& aPresContext,
NS_IMETHODIMP
nsComboboxControlFrame::GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame)
{
//nsresult rv = nsScrollFrame::GetFrameForPoint(aPoint, aFrame);
nsresult rv = GetFrameForPointUsing(aPoint, nsnull, aFrame);
if (NS_OK == rv) {
if (*aFrame != this) {
//mHitFrame = *aFrame;
*aFrame = this;
}
return NS_OK;
}
*aFrame = this;
return NS_OK;
}
nsresult
nsComboboxControlFrame::GetFrameForPointUsing(const nsPoint& aPoint,
nsIAtom* aList,
nsIFrame** aFrame)
{
*aFrame = this;
return NS_OK;
}
//----------------------------------------------------------------------
// nsIPluggableEventListener
//----------------------------------------------------------------------
//----------------------------------------------------------------------
NS_IMETHODIMP nsComboboxControlFrame::PluggableEventHandler(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus)
{
HandleEvent(aPresContext, aEvent, aEventStatus);
//aEventStatus = nsEventStatus_eConsumeNoDefault;
return NS_OK;
}
//----------------------------------------------------------------------
NS_IMETHODIMP nsComboboxControlFrame::PluggableGetFrameForPoint(const nsPoint& aPoint,
nsIFrame** aFrame)
{
return GetFrameForPoint(aPoint, aFrame);
}
//----------------------------------------------------------------------
// nsIComboboxControlFrame
//----------------------------------------------------------------------
//----------------------------------------------------------------------
NS_IMETHODIMP
nsComboboxControlFrame::SetDropDown(nsIFrame* aPlaceHolderFrame, nsIFrame* aDropDownFrame)
{
@ -831,10 +755,10 @@ nsComboboxControlFrame::SetDropDown(nsIFrame* aPlaceHolderFrame, nsIFrame* aDrop
// Let's get the currently selected item, but we make the call using the Interface
mListControlFrame->GetSelectedItem(mTextStr);
AppendChildren(mPlaceHolderFrame, PR_FALSE);
return NS_OK;
}
//--------------------------------------------------------------
NS_IMETHODIMP
nsComboboxControlFrame::SetDropDownStyleContexts(nsIStyleContext * aVisible, nsIStyleContext * aHidden)
@ -879,19 +803,9 @@ nsComboboxControlFrame::ListWasSelected(nsIPresContext* aPresContext)
SetFocus(PR_TRUE, PR_TRUE);
}
return NS_OK;
}
NS_IMETHODIMP nsComboboxControlFrame::SetProperty(nsIAtom* aName, const nsString& aValue)
{
return NS_OK;
}
NS_IMETHODIMP nsComboboxControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
return NS_OK;
}
nsresult nsComboboxControlFrame::RequiresWidget(PRBool& aRequiresWidget)
{
@ -900,3 +814,23 @@ nsresult nsComboboxControlFrame::RequiresWidget(PRBool& aRequiresWidget)
}
NS_IMETHODIMP nsComboboxControlFrame::SetProperty(nsIAtom* aName, const nsString& aValue)
{
nsIFormControlFrame* fcFrame = nsnull;
nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
if ((NS_SUCCEEDED(result)) && (nsnull != fcFrame)) {
return fcFrame->SetProperty(aName, aValue);
}
return result;
}
NS_IMETHODIMP nsComboboxControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
nsIFormControlFrame* fcFrame = nsnull;
nsresult result = mListFrame->QueryInterface(kIFormControlFrameIID, (void**)&fcFrame);
if ((NS_SUCCEEDED(result)) && (nsnull != fcFrame)) {
return fcFrame->GetProperty(aName, aValue);
}
return result;
}

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

@ -19,12 +19,11 @@
#ifndef nsComboboxControlFrame_h___
#define nsComboboxControlFrame_h___
#include "nsHTMLContainerFrame.h"
#include "nsIFormControlFrame.h"
#include "nsIComboboxControlFrame.h"
#ifdef PLUGGABLE_EVENTS
#include "nsIPluggableEventListener.h"
#endif
class nsButtonControlFrame;
class nsTextControlFrame;
@ -37,9 +36,7 @@ class nsIListControlFrame;
class nsComboboxControlFrame : public nsHTMLContainerFrame,
public nsIFormControlFrame,
public nsIComboboxControlFrame
#ifdef PLUGGABLE_EVENTS
public nsIPluggableEventListener
#endif
{
public:
nsComboboxControlFrame();
@ -84,6 +81,9 @@ public:
// nsIFormControLFrame
NS_IMETHOD SetProperty(nsIAtom* aName, const nsString& aValue);
NS_IMETHOD GetProperty(nsIAtom* aName, nsString& aValue);
virtual void PostCreateWidget(nsIPresContext* aPresContext,
nscoord& aWidth,
nscoord& aHeight);
//nsTextControlFrame* GetTextFrame() { return mTextFrame; }
@ -117,9 +117,6 @@ public:
NS_IMETHOD GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame);
nsresult GetFrameForPointUsing(const nsPoint& aPoint,
nsIAtom* aList,
nsIFrame** aFrame);
// A Static Helper Functions
// This refreshes a particular pseudo style content when a "ReResolveStyleContent" happens
@ -132,16 +129,6 @@ public:
// nsIFormMouseListener
virtual void MouseClicked(nsIPresContext* aPresContext);
// nsIPluggableEventListener
NS_IMETHOD PluggableEventHandler(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
nsEventStatus& aEventStatus);
NS_IMETHOD PluggableGetFrameForPoint(const nsPoint& aPoint,
nsIFrame** aFrame);
//static PRInt32 gSpacing;
//nsIComboboxControlFrame
NS_IMETHOD SetDropDown(nsIFrame* aPlaceHolderFrame, nsIFrame* aDropDownFrame);
NS_IMETHOD SetDropDownStyleContexts(nsIStyleContext * aVisible, nsIStyleContext * aHidden);
@ -154,17 +141,14 @@ protected:
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer);
nsIWidget* GetWindowTemp(nsIView *aView); // XXX temporary
virtual PRIntn GetSkipSides() const;
nsFormFrame* mFormFrame; // Parent Form Frame
nsIFrame * mPlaceHolderFrame;
nsIFrame * mListFrame; // Generic nsIFrame
nsIListControlFrame * mListControlFrame; // Specific ListControl Interface
nsRect mButtonRect; // The Arrow Button's Rect cached for Painting
// DropDown List Visibility Styles
nsIStyleContext * mVisibleStyleContext; // Style for the DropDown List to make it visible
nsIStyleContext * mHiddenStyleContext; // Style for the DropDown List to make it hidden
@ -180,7 +164,6 @@ protected:
nsIStyleContext * mBlockTextSelectedStyle; // Style when selected and it doesn't have focus
nsIStyleContext * mBlockTextSelectedFocusStyle; // Style when selected and it has focus
PRBool mFirstTime;
// State data members

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

@ -64,13 +64,13 @@
#include "nsFormFrame.h"
#include "nsIScrollableView.h"
#define CSS_NOTSET -1
#define ATTR_NOTSET -1
// Constants
const char * kNormal = "";
const char * kSelected = "SELECTED";
const char * kSelectedFocus = "SELECTEDFOCUS";
//XXX: This is temporary. It simulates psuedo states by using a attribute selector on
// -moz-option-selected in the ua.css style sheet. This will not be needed when
//The event state manager is functional. KMM
const char * kMozSelected = "-moz-option-selected";
static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID);
@ -116,7 +116,6 @@ nsListControlFrame::~nsListControlFrame()
NS_IF_RELEASE(mComboboxFrame);
}
//----------------------------------------------------------------------
NS_IMPL_ADDREF(nsListControlFrame)
NS_IMPL_RELEASE(nsListControlFrame)
@ -146,6 +145,11 @@ nsListControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
NS_IMETHODIMP
nsListControlFrame::GetFrameForPoint(const nsPoint& aPoint, nsIFrame** aFrame)
{
// Save the result of GetFrameForPointUsing in the mHitFrame member variable.
// mHitFrame is used later in the HandleLikeListEvent to determine what was clicked on.
// XXX: This is kludgy, but there doesn't seem to be a way to get what was just clicked
// on in the HandleEvent. The GetFrameForPointUsing is always called before the HandleEvent.
//
nsresult rv;
nsIFrame *childFrame;
@ -178,9 +182,14 @@ nsListControlFrame::GetFrameForPointUsing(const nsPoint& aPoint,
nsIFrame* firstKid = nsnull;
// XXX:Hack. This should not be necessary.
// Get the scrolled offset from the view.
//
// XXX:Hack. This should not be necessary. It is only required because we interpose on the
// normal event flow by redirecting to the listbox using the SetVFlags(NS_DONT_CHECK_CHILDREN).
// What we should really do is have a manager which the option items report there events to.
// The listbox frame would be the manager for the option items. KMM.
//
//
// This is needed because:
// The scrolled view is below the nsListControlFrame's ScrollingView in
// the view hierarchy. This presents a problem for event translation when the events
@ -227,8 +236,6 @@ nsListControlFrame::GetFrameForPointUsing(const nsPoint& aPoint,
}
NS_RELEASE(content);
return kid->GetFrameForPoint(tmp, aFrame);
//*aFrame = kid;
//return NS_OK;
}
kid->GetNextSibling(&kid);
}
@ -286,7 +293,11 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
nsIFrame* childFrame = nsnull;
mContentFrame->FirstChild(nsnull, &childFrame);
PRInt32 numChildren = LengthOf(childFrame);
PRBool needsVerticalScrollbar = (numChildren > mNumRows);
PRBool needsVerticalScrollbar = PR_FALSE;
if (PR_FALSE == mInDropDownMode) {
PRBool needsVerticalScrollbar = (numChildren > mNumRows);
}
//--Calculate a width just big enough for the scrollframe to shrink around the
//longest element in the list
@ -306,14 +317,12 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
// XXX: This should be changed to do the inherited reflow unconstrained for
// the width to get the real desired width. GetDesiredSize is limited to
// text strings.
//XXX: TODO: Use the width and height of an the first reflow to determine how high and wide
//to make the listbox, instead of calculating it. The second reflow can be done actually position
//the frames correctly using: tempReflowState.reason = eReflowReason_Resize;
GetDesiredSize(&aPresContext, aReflowState, desiredSize, desiredLineSize);
// Only set to the desired width if it hasn't been explicitly defined through CSS.
// GetDesiredSize must still be done above to calculate the desired height.
if (NS_UNCONSTRAINEDSIZE == tempReflowState.computedWidth) {
tempReflowState.computedWidth = desiredLineSize.width;
}
// Retrieve the scrollbar's width and height
float sbWidth = 0.0;
float sbHeight = 0.0;;
@ -324,6 +333,16 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
nscoord scrollbarWidth = NSToCoordRound(sbWidth);
nscoord scrollbarHeight = NSToCoordRound(sbHeight);
if (mInDropDownMode) {
// For drop-down lists, always size the width of the list based on
// the desired lineSize.
tempReflowState.computedWidth = desiredLineSize.width + scrollbarWidth;
} else if (NS_UNCONSTRAINEDSIZE == tempReflowState.computedWidth) {
// Only set to the desired width if it hasn't been explicitly defined through CSS.
// GetDesiredSize must still be done above to calculate the desired height.
tempReflowState.computedWidth = desiredLineSize.width;
}
// Add vertical scrollbar, Always add it in,
// even though the vertical scrollbar is not needed all the time
// the inherited Reflow: allways leave space for the scrollbar by
@ -333,10 +352,8 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
// Now that we have calculated the width required to just shrink around the longest line.
// Go ahead and reflow
// Do the inherited Reflow. This reflow uses the computed widths which
// are setup above.
// Don't set the height. Let the height be unconstrained
nsScrollFrame::Reflow(aPresContext,
@ -368,12 +385,13 @@ nsListControlFrame::Reflow(nsIPresContext& aPresContext,
aDesiredSize.maxElementSize->height = aDesiredSize.height;
}
//XXX: Set the min element size here to the desired element size here??
// XXX: Set the min element size here to the desired element size here??
// Restore to original reflow state.
tempReflowState.computedWidth = saveComputedWidth;
tempReflowState.availableWidth = saveAvailableWidth;
aStatus = NS_FRAME_COMPLETE;
return NS_OK;
}
@ -443,12 +461,18 @@ nsListControlFrame::GetFont(nsIPresContext* aPresContext,
void nsListControlFrame::DisplaySelected(nsIContent* aContent)
{
//XXX: This is temporary. It simulates psuedo states by using a attribute selector on
// -moz-option-selected in the ua.css style sheet. This will not be needed when
// The event state manager is functional. KMM
nsCOMPtr<nsIAtom> selectedAtom ( dont_QueryInterface(NS_NewAtom(kMozSelected)));
aContent->SetAttribute(kNameSpaceID_None, selectedAtom, "", PR_TRUE);
}
void nsListControlFrame::DisplayDeselected(nsIContent* aContent)
{
//XXX: This is temporary. It simulates psuedo states by using a attribute selector on
// -moz-option-selected in the ua.css style sheet. This will not be needed when
// The event state manager is functional. KMM
nsCOMPtr<nsIAtom> selectedAtom ( dont_QueryInterface(NS_NewAtom(kMozSelected)));
aContent->UnsetAttribute(kNameSpaceID_None, selectedAtom, PR_TRUE);
}
@ -465,7 +489,7 @@ void nsListControlFrame::UpdateItem(nsIContent* aContent, PRBool aSelected)
//----------------------------------------------------------------------
PRInt32 nsListControlFrame::SetContentSelected(nsIFrame * aHitFrame,
nsIContent *& aHitContent,
PRBool aIsSelected)
PRBool aDisplaySelected)
{
PRInt32 index = 0;
nsIFrame* kid;
@ -476,7 +500,8 @@ PRInt32 nsListControlFrame::SetContentSelected(nsIFrame * aHitFrame,
nsIContent* content;
kid->GetContent(&content);
aHitContent = content;
//XXX: DisplaySelected(aHitContent);
if (PR_TRUE == aDisplaySelected)
DisplaySelected(aHitContent);
return index;
}
kid->GetNextSibling(&kid);
@ -557,7 +582,7 @@ NS_IMETHODIMP nsListControlFrame::HandleLikeListEvent(nsIPresContext& aPresConte
if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN) {
PRInt32 oldSelectedIndex = mSelectedIndex;
mSelectedIndex = (PRInt32)SetContentSelected(mHitFrame, mHitContent, PR_TRUE);
mSelectedIndex = (PRInt32)SetContentSelected(mHitFrame, mHitContent, PR_FALSE);
if (-1 < mSelectedIndex) {
PRBool wasSelected = IsFrameSelected(mSelectedIndex);
SetFrameSelected(mSelectedIndex, PR_TRUE);
@ -663,13 +688,12 @@ NS_IMETHODIMP nsListControlFrame::HandleLikeDropDownListEvent(nsIPresContext& aP
// Now cache the the newly hit frame and content as the "current" values
mCurrentHitFrame = mHitFrame;
mCurrentHitContent = mHitContent;
}
} else if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP) {
// Start by finding the newly "hit" content from the hit frame
PRInt32 index = SetContentSelected(mHitFrame, mHitContent, PR_FALSE);
PRInt32 index = SetContentSelected(mHitFrame, mHitContent, PR_TRUE);
if (-1 < index) {
nsIDOMHTMLOptionElement* option = nsnull;
@ -905,7 +929,6 @@ nsListControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
for (PRUint32 i = 0; i < numOptions; i++) {
nsIDOMHTMLOptionElement* option = GetOption(*options, i);
if (option) {
//option->CompressContent();
nsAutoString text;
if (NS_CONTENT_ATTR_HAS_VALUE != option->GetText(text)) {
continue;
@ -936,28 +959,14 @@ nsListControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
aPresContext->GetPixelsToTwips(&p2t);
aPresContext->GetScaledPixelsToTwips(&sp2t);
//nscoord scrollbarWidth = 0;
//nscoord scrollbarHeight = 0;
//GetScrollBarDimensions(*aPresContext, scrollbarWidth, scrollbarHeight);
if (mInDropDownMode) {
//PRUint32 numOptions;
//options->GetLength(&numOptions);
nscoord extra = desiredSize.height - (rowHeight * mNumRows);
mNumRows = (numOptions > 20 ? 20 : numOptions);
desiredSize.height = (mNumRows * rowHeight) + extra;
if (mNumRows < 21) {
//calcSize.width += scrollbarWidth;
}
}
aDesiredLayoutSize.width = desiredSize.width;
// account for vertical scrollbar, if present
//if (!widthExplicit && ((mNumRows < numOptions) || mIsComboBox)) {
//if (!widthExplicit && (mNumRows < (PRInt32)numOptions)) {
// aDesiredLayoutSize.width += scrollbarWidth;
// }
// XXX put this in widget library, combo boxes are fixed height (visible part)
//aDesiredLayoutSize.height = (mIsComboBox)
@ -972,18 +981,7 @@ nsListControlFrame::GetDesiredSize(nsIPresContext* aPresContext,
aDesiredWidgetSize.width = maxWidth;
aDesiredWidgetSize.height = rowHeight;
//if (mIsComboBox) { // add in pull down size
// PRInt32 extra = NSIntPixelsToTwips(10, p2t*scale);
// 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;
//}
if (aDesiredLayoutSize.maxElementSize) {
aDesiredLayoutSize.maxElementSize->width = minSize.width;
aDesiredLayoutSize.maxElementSize->height = minSize.height;
@ -1394,6 +1392,7 @@ nsListControlFrame::SetFocus(PRBool aOn, PRBool aRepaint)
// XXX I don't know whether to use the aRepaint flag as last param
// in this call?
if (mSelectedContent) {
//XXX: Need correct attribute here
mSelectedContent->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::kClass, (aOn?kSelectedFocus:kNormal), PR_TRUE);
}
@ -1420,16 +1419,6 @@ nsListControlFrame::GetSelectedItem(nsString & aStr)
return NS_OK;
}
NS_IMETHODIMP nsListControlFrame::SetProperty(nsIAtom* aName, const nsString& aValue)
{
return NS_OK;
}
NS_IMETHODIMP nsListControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
return NS_OK;
}
nsresult nsListControlFrame::RequiresWidget(PRBool& aRequiresWidget)
{
aRequiresWidget = PR_FALSE;
@ -1437,4 +1426,72 @@ nsresult nsListControlFrame::RequiresWidget(PRBool& aRequiresWidget)
}
PRInt32 nsListControlFrame::GetNumberOfOptions()
{
nsIDOMHTMLCollection* options = GetOptions(mContent);
if (!options) {
return 0;
}
PRUint32 numOptions;
options->GetLength(&numOptions);
NS_RELEASE(options);
return(numOptions);
}
NS_IMETHODIMP nsListControlFrame::SetProperty(nsIAtom* aName, const nsString& aValue)
{
if (nsHTMLAtoms::selected == aName) {
return NS_ERROR_INVALID_ARG; // Selected is readonly according to spec.
} else if (nsHTMLAtoms::selectedindex == aName) {
PRInt32 error = 0;
PRInt32 selectedIndex = aValue.ToInteger(&error, 10); // Get index from aValue
if (error) {
return NS_ERROR_INVALID_ARG; // Couldn't convert to integer
} else {
SetFrameSelected(selectedIndex, PR_TRUE);
}
} else {
//XXX: TODO What about all othe other properties that form elements can set here?
// return nsFormControlFrame::SetProperty(aName, aValue);
}
return NS_OK;
}
NS_IMETHODIMP nsListControlFrame::GetProperty(nsIAtom* aName, nsString& aValue)
{
// Get the selected value of option from local cache (optimization vs. widget)
if (nsHTMLAtoms::selected == aName) {
PRInt32 error = 0;
PRBool selected = PR_FALSE;
PRInt32 index = aValue.ToInteger(&error, 10); // Get index from aValue
if (error == 0)
selected = IsFrameSelected(index);
nsFormControlHelper::GetBoolString(selected, aValue);
// For selectedIndex, get the value from the widget
} else if (nsHTMLAtoms::selectedindex == aName) {
// Spin through loooking for the first selection in the list
PRInt32 index = 0;
PRInt32 maxOptions = GetNumberOfOptions();
PRInt32 selectedIndex = -1;
for (index = 0; index < maxOptions; index++) {
PRBool isSelected = PR_FALSE;
if (PR_TRUE == IsFrameSelected(index)) {
selectedIndex = isSelected;
break;
}
}
aValue.Append(selectedIndex, 10);
} else {
//XXX: TODO: What about all of the other form properties???
//return nsFormControlFrame::GetProperty(aName, aValue);
}
return NS_OK;
}

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

@ -65,6 +65,7 @@ public:
NS_IMETHOD SetInitialChildList(nsIPresContext& aPresContext,
nsIAtom* aListName,
nsIFrame* aChildList);
NS_IMETHOD Reflow(nsIPresContext& aCX,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
@ -167,6 +168,8 @@ protected:
nsListControlFrame();
virtual ~nsListControlFrame();
PRInt32 GetNumberOfOptions();
nsIFrame * GetOptionFromChild(nsIFrame* aParentFrame);
nsresult GetFrameForPointUsing(const nsPoint& aPoint,
@ -194,7 +197,7 @@ protected:
nsEventStatus& aEventStatus);
PRInt32 SetContentSelected(nsIFrame * aHitFrame,
nsIContent *& aHitContent,
PRBool aIsSelected);
PRBool aDisplaySelected);
// Data Members
nsFormFrame* mFormFrame;

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

@ -91,6 +91,8 @@ static NS_DEFINE_IID(kIDOMHTMLImageElementIID, NS_IDOMHTMLIMAGEELEMENT_IID);
static NS_DEFINE_IID(kIDOMCharacterDataIID, NS_IDOMCHARACTERDATA_IID);
static NS_DEFINE_IID(kScrollViewIID, NS_ISCROLLABLEVIEW_IID);
static NS_DEFINE_IID(kIFormControlIID, NS_IFORMCONTROL_IID);
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
// Structure used when constructing formatting object trees.
struct nsFrameItems {
@ -2010,28 +2012,36 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContext,
PRBool aIsAbsolutelyPositioned,
PRBool & aFrameHasBeenInitialized,
PRBool aIsFixedPositioned,
nsAbsoluteItems& aFixedItems)
nsAbsoluteItems& aFixedItems,
nsFrameItems& aFrameItems)
{
#define NS_FRAME_BASED_COMBO_WORKS 0
nsresult rv = NS_OK;
nsWidgetRendering mode;
aPresContext->GetWidgetRenderingMode(&mode);
const PRInt32 kNoSizeSpecified = -1;
if (eWidgetRendering_Gfx == mode) {
// Construct a frame-based listbox or combobox
nsIDOMHTMLSelectElement* select = nsnull;
PRInt32 size = 1;
PRInt32 size = 1;
nsresult result = aContent->QueryInterface(kIDOMHTMLSelectElementIID, (void**)&select);
if (NS_OK == result) {
result = select->GetSize(&size);
if (1 == size) {
if (! NS_FRAME_BASED_COMBO_WORKS) {
rv = NS_NewSelectControlFrame(aNewFrame);
} else {
if ((1 == size) || (kNoSizeSpecified == size)) {
// Construct a frame-based combo box
nsIFrame * comboboxFrame;
rv = NS_NewComboboxControlFrame(comboboxFrame);
nsIComboboxControlFrame* comboBox;
if (NS_OK == comboboxFrame->QueryInterface(kIComboboxControlFrameIID, (void**)&comboBox)) {
nsIFrame* geometricParent = aParentFrame;
if (aIsAbsolutelyPositioned) {
geometricParent = aAbsoluteItems.containingBlock;
} else if (aIsFixedPositioned) {
geometricParent = aFixedItems.containingBlock;
}
comboboxFrame->Init(*aPresContext, aContent, geometricParent, aStyleContext, nsnull);
nsIComboboxControlFrame* comboBox = nsnull;
if (NS_OK == comboboxFrame->QueryInterface(kIComboboxControlFrameIID, (void**)&comboBox)) {
nsIFrame * listFrame;
rv = NS_NewListControlFrame(listFrame);
@ -2042,19 +2052,53 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContext,
listControlFrame->SetComboboxFrame(comboboxFrame);
}
InitializeScrollFrame(listFrame, aPresContext, aContent, comboboxFrame, aStyleContext,
aAbsoluteItems, aNewFrame, aFixedItems, aIsAbsolutelyPositioned,
aIsFixedPositioned, PR_TRUE);
//XXX: TODO: Make sure that a failure to resolve the following
//pseudo style will still work.
nsIFrame* placeholderFrame;
// Set up the Pseudo Style contents
// Dropdown list style
nsCOMPtr<nsIStyleContext> listStyle;
aPresContext->ResolvePseudoStyleContextFor
(aContent, nsHTMLAtoms::dropDownList, aStyleContext, PR_FALSE,
getter_AddRefs(listStyle));
// Dropdown list visible style
nsCOMPtr<nsIStyleContext> visiblePseudoStyle;
aPresContext->ResolvePseudoStyleContextFor
(aContent, nsHTMLAtoms::dropDownVisible, aStyleContext, PR_FALSE,
getter_AddRefs(visiblePseudoStyle));
// Dropdown list hidden style
nsCOMPtr<nsIStyleContext> hiddenPseudoStyle;
aPresContext->ResolvePseudoStyleContextFor
(aContent, nsHTMLAtoms::dropDownHidden, aStyleContext, PR_FALSE,
getter_AddRefs(hiddenPseudoStyle));
// Initialize the scroll frame as absolutely positioned.
InitializeScrollFrame(listFrame, aPresContext, aContent, comboboxFrame, listStyle,
aAbsoluteItems, aNewFrame, aFixedItems, PR_TRUE,
PR_FALSE, PR_TRUE);
// Set flag so the events go to the listFrame not child frames.
// XXX: We should replace this with a real widget manager similar
// to how the nsFormControlFrame works.
// Re-directing events is a temporary Kludge.
nsIView *listView;
listFrame->GetView(&listView);
NS_ASSERTION(nsnull != listView,"ListFrame's view is nsnull");
listView->SetViewFlags(NS_VIEW_FLAG_DONT_CHECK_CHILDREN);
// Create a place holder frame for the dropdown list
nsIFrame* placeholderFrame = nsnull;
CreatePlaceholderFrameFor(aPresContext, aContent, aNewFrame, aStyleContext,
aParentFrame, placeholderFrame);
aFrameItems.AddChild(placeholderFrame);
// Add the absolutely positioned frame to its containing block's list
// of child frames
if (aIsAbsolutelyPositioned)
aAbsoluteItems.AddChild(aNewFrame);
aAbsoluteItems.AddChild(listFrame);
listFrame = aNewFrame;
@ -2063,18 +2107,11 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContext,
// and this method initializes the ComboBox's selection state
comboBox->SetDropDown(placeholderFrame, listFrame);
// Set up the Pseudo Style contents
//XXX: What should happend if resolving the pseudo style fails?
nsCOMPtr<nsIStyleContext> visiblePseudoStyle;
aPresContext->ResolvePseudoStyleContextFor
(aContent, nsHTMLAtoms::dropDownVisible, aStyleContext, PR_FALSE,
getter_AddRefs(visiblePseudoStyle));
nsCOMPtr<nsIStyleContext> hiddenPseudoStyle;
aPresContext->ResolvePseudoStyleContextFor
(aContent, nsHTMLAtoms::dropDownHidden, aStyleContext, PR_FALSE,
getter_AddRefs(hiddenPseudoStyle));
// Set up the Pseudo Style contents for combo box button pressed and
// out.
//XXX: TODO: Make this work even if resolving the pseudo style fails.
nsCOMPtr<nsIStyleContext> outPseudoStyle;
aPresContext->ResolvePseudoStyleContextFor
(aContent, nsHTMLAtoms::dropDownBtnOut, aStyleContext, PR_FALSE,
@ -2086,22 +2123,33 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContext,
comboBox->SetDropDownStyleContexts(visiblePseudoStyle, hiddenPseudoStyle);
comboBox->SetButtonStyleContexts(outPseudoStyle, pressPseudoStyle);
nsIFrame* frame = nsnull;
if (NS_OK == comboboxFrame->QueryInterface(kIFrameIID, (void**)&frame)) {
nsFrameItems childItems;
frame->SetInitialChildList(*aPresContext, nsnull,
childItems.childList);
}
aProcessChildren = PR_FALSE;
nsHTMLContainerFrame::CreateViewForFrame(*aPresContext, listFrame,
aStyleContext, PR_TRUE);
//XXX: TODO: Need to set an option on the view that was created for the dropdown list
//to be a borderless top-level window.
aNewFrame = comboboxFrame;
}
}
aFrameHasBeenInitialized = PR_TRUE;
}
} else {
// Construct a frame-based list box
nsIFrame * listFrame;
rv = NS_NewListControlFrame(listFrame);
aNewFrame = listFrame;
InitializeScrollFrame(listFrame, aPresContext, aContent, aParentFrame, aStyleContext,
aAbsoluteItems, aNewFrame, aFixedItems, aIsAbsolutelyPositioned, PR_FALSE, PR_TRUE);
// Set flag so the events go to the listFrame not child frames.
// Set flag so the events go to the listFrame not child frames.
// XXX: We should replace this with a real widget manager similar
// to how the nsFormControlFrame works.
// Re-directing events is a temporary Kludge.
nsIView *listView;
listFrame->GetView(&listView);
NS_ASSERTION(nsnull != listView,"ListFrame's view is nsnull");
@ -2114,7 +2162,7 @@ nsCSSFrameConstructor::ConstructSelectFrame(nsIPresContext* aPresContext,
}
}
else {
// Not frame based. Use a frame which creates a native widget instead.
// Not frame based. Use a SelectFrame which creates a native widget.
rv = NS_NewSelectControlFrame(aNewFrame);
}
@ -2208,7 +2256,7 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext,
newFrame, processChildren,
isAbsolutelyPositioned,
frameHasBeenInitialized,
isFixedPositioned, aFixedItems);
isFixedPositioned, aFixedItems, aFrameItems);
}
else if (nsHTMLAtoms::applet == aTag) {
isReplaced = PR_TRUE;

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

@ -332,7 +332,8 @@ protected:
PRBool aIsAbsolutelyPositioned,
PRBool & aFrameHasBeenInitialized,
PRBool aIsFixedPositioned,
nsAbsoluteItems& aFixedItems);
nsAbsoluteItems& aFixedItems,
nsFrameItems& aFrameItems);
nsresult ConstructFrameByTag(nsIPresContext* aPresContext,
nsIContent* aContent,

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

@ -883,14 +883,33 @@ sourcetext {
display: none;
}
:dropdown-visible {
:-moz-dropdown-visible {
visibility: visible;
}
:dropdown-hidden {
:-moz-dropdown-hidden {
visibility: hidden;
}
:-moz-dropdown-btn-out {
border: 2px outset #c0c0c0;
background-color: rgb(206, 207, 206);
}
:-moz-dropdown-btn-pressed {
border: 2px inset #c0c0c0;
background-color: rgb(206, 207, 206);
}
:-moz-dropdown-list {
position:absolute;
height:200px;
width:100px;
background-color:white;
border: 1px solid blue;
}
:combobox-text {
color: black;
padding-left: 2px;