From 09d003848a4d35eaa19699d761e2748e5761060c Mon Sep 17 00:00:00 2001 From: "evaughan%netscape.com" Date: Wed, 30 Jun 1999 22:17:43 +0000 Subject: [PATCH] Added anonymous node support. Added splitters Added Grippies. git-svn-id: svn://10.0.0.236/trunk@37561 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/shared/public/nsXULAtoms.h | 3 + mozilla/content/shared/src/nsXULAtoms.cpp | 9 + mozilla/layout/base/nsCSSFrameConstructor.cpp | 228 +++++++-------- mozilla/layout/base/nsCSSFrameConstructor.h | 15 +- mozilla/layout/forms/nsFileControlFrame.cpp | 267 ++++++++---------- mozilla/layout/forms/nsFileControlFrame.h | 80 +++++- .../generic/nsIAnonymousContentCreator.h | 43 +++ .../base/src/nsIAnonymousContentCreator.h | 43 +++ .../html/forms/src/nsFileControlFrame.cpp | 267 ++++++++---------- .../html/forms/src/nsFileControlFrame.h | 80 +++++- .../html/style/src/nsCSSFrameConstructor.cpp | 228 +++++++-------- .../html/style/src/nsCSSFrameConstructor.h | 15 +- mozilla/layout/xul/base/src/Makefile.in | 2 + mozilla/layout/xul/base/src/makefile.win | 4 + mozilla/layout/xul/base/src/nsBoxFrame.cpp | 236 +++++++++------- mozilla/layout/xul/base/src/nsBoxFrame.h | 1 + mozilla/layout/xul/base/src/nsGrippyFrame.cpp | 201 +++++++++++++ mozilla/layout/xul/base/src/nsGrippyFrame.h | 57 ++++ .../layout/xul/base/src/nsScrollbarFrame.cpp | 68 +++++ .../layout/xul/base/src/nsScrollbarFrame.h | 12 +- mozilla/layout/xul/base/src/nsSliderFrame.cpp | 50 +++- mozilla/layout/xul/base/src/nsSliderFrame.h | 8 +- .../layout/xul/base/src/nsSplitterFrame.cpp | 173 ++++++++++++ mozilla/layout/xul/base/src/nsSplitterFrame.h | 65 +++++ mozilla/layout/xul/content/src/nsXULAtoms.cpp | 9 + mozilla/layout/xul/content/src/nsXULAtoms.h | 3 + mozilla/xpfe/AppCores/src/makefile.win | 12 +- mozilla/xpfe/AppCores/xul/Makefile.in | 6 +- .../xul/resources/grippy-horizontal-after.gif | Bin 0 -> 157 bytes .../resources/grippy-horizontal-before.gif | Bin 0 -> 157 bytes .../xul/resources/grippy-vertical-after.gif | Bin 0 -> 145 bytes .../xul/resources/grippy-vertical-before.gif | Bin 0 -> 144 bytes .../xpfe/AppCores/xul/resources/grippy.gif | Bin 189 -> 0 bytes .../xpfe/AppCores/xul/resources/grippyO.gif | Bin 193 -> 0 bytes mozilla/xpfe/browser/src/xul.css | 23 +- 35 files changed, 1507 insertions(+), 701 deletions(-) create mode 100644 mozilla/layout/generic/nsIAnonymousContentCreator.h create mode 100644 mozilla/layout/html/base/src/nsIAnonymousContentCreator.h create mode 100644 mozilla/layout/xul/base/src/nsGrippyFrame.cpp create mode 100644 mozilla/layout/xul/base/src/nsGrippyFrame.h create mode 100644 mozilla/layout/xul/base/src/nsSplitterFrame.cpp create mode 100644 mozilla/layout/xul/base/src/nsSplitterFrame.h create mode 100644 mozilla/xpfe/AppCores/xul/resources/grippy-horizontal-after.gif create mode 100644 mozilla/xpfe/AppCores/xul/resources/grippy-horizontal-before.gif create mode 100644 mozilla/xpfe/AppCores/xul/resources/grippy-vertical-after.gif create mode 100644 mozilla/xpfe/AppCores/xul/resources/grippy-vertical-before.gif delete mode 100644 mozilla/xpfe/AppCores/xul/resources/grippy.gif delete mode 100644 mozilla/xpfe/AppCores/xul/resources/grippyO.gif diff --git a/mozilla/content/shared/public/nsXULAtoms.h b/mozilla/content/shared/public/nsXULAtoms.h index 32b517c1027..54c7bf2a462 100644 --- a/mozilla/content/shared/public/nsXULAtoms.h +++ b/mozilla/content/shared/public/nsXULAtoms.h @@ -95,6 +95,9 @@ public: static nsIAtom* thumb; static nsIAtom* toggled; + static nsIAtom* grippy; + static nsIAtom* splitter; + static nsIAtom* collapse; }; #endif /* nsXULAtoms_h___ */ diff --git a/mozilla/content/shared/src/nsXULAtoms.cpp b/mozilla/content/shared/src/nsXULAtoms.cpp index 3d7fb4f7ae1..f3d947622a3 100644 --- a/mozilla/content/shared/src/nsXULAtoms.cpp +++ b/mozilla/content/shared/src/nsXULAtoms.cpp @@ -73,6 +73,9 @@ nsIAtom* nsXULAtoms::increment; nsIAtom* nsXULAtoms::pageincrement; nsIAtom* nsXULAtoms::thumb; nsIAtom* nsXULAtoms::toggled; +nsIAtom* nsXULAtoms::grippy; +nsIAtom* nsXULAtoms::splitter; +nsIAtom* nsXULAtoms::collapse; nsIAtom* nsXULAtoms::widget; nsIAtom* nsXULAtoms::window; @@ -140,6 +143,9 @@ void nsXULAtoms::AddrefAtoms() { pageincrement = NS_NewAtom("pageincrement"); thumb = NS_NewAtom("thumb"); toggled = NS_NewAtom("toggled"); + grippy = NS_NewAtom("grippy"); + splitter = NS_NewAtom("splitter"); + collapse = NS_NewAtom("collapse"); widget = NS_NewAtom("widget"); @@ -198,6 +204,9 @@ void nsXULAtoms::ReleaseAtoms() { NS_RELEASE(pageincrement); NS_RELEASE(thumb); NS_RELEASE(toggled); + NS_RELEASE(grippy); + NS_RELEASE(splitter); + NS_RELEASE(collapse); NS_RELEASE(widget); NS_RELEASE(window); diff --git a/mozilla/layout/base/nsCSSFrameConstructor.cpp b/mozilla/layout/base/nsCSSFrameConstructor.cpp index 6ba277873b9..412313ba447 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/base/nsCSSFrameConstructor.cpp @@ -61,6 +61,8 @@ #include "nsCSSAtoms.h" #include "nsIDeviceContext.h" #include "nsTextFragment.h" +#include "nsISupportsArray.h" +#include "nsIAnonymousContentCreator.h" #ifdef INCLUDE_XUL #include "nsXULAtoms.h" @@ -74,7 +76,6 @@ #include "nsIDOMDocument.h" #include "nsDocument.h" - nsresult NS_NewTabFrame ( nsIFrame** aNewFrame ); @@ -114,6 +115,11 @@ NS_NewScrollbarButtonFrame ( nsIFrame** aNewFrame ); nsresult NS_NewScrollbarFrame ( nsIFrame** aNewFrame ); +nsresult +NS_NewGrippyFrame ( nsIFrame** aNewFrame ); + +nsresult +NS_NewSplitterFrame ( nsIFrame** aNewFrame ); #endif //static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); @@ -1275,11 +1281,26 @@ nsCSSFrameConstructor::ConstructTableGroupFrameOnly(nsIPresContext* aPr // Create some anonymous extras within the tree body. if (aTableCreator.IsTreeCreator()) { - nsCOMPtr tag; - aContent->GetTag(*getter_AddRefs(tag)); - CreateAnonymousXULContent(aPresContext, tag, aState, aContent, aNewGroupFrame, - childItems); - + // BEGIN ANONYMOUS + // See if our parent is a tree. + nsCOMPtr tag; + aContent->GetTag(*getter_AddRefs(tag)); + + if (tag == nsXULAtoms::treechildren) { + // See if our parent is a tree. + nsCOMPtr grandPappy; + aContent->GetParent(*getter_AddRefs(grandPappy)); + grandPappy->GetTag(*getter_AddRefs(tag)); + nsCOMPtr element = do_QueryInterface(grandPappy); + nsString mode; + element->GetAttribute("mode", mode); + if (tag.get() == nsXULAtoms::tree) { + // We will want to have a scrollbar. + ((nsTreeRowGroupFrame*)aParentFrame)->SetFrameConstructor(this); + ((nsTreeRowGroupFrame*)aParentFrame)->SetShouldHaveScrollbar(); + } + } + // END ANONYMOUS const nsStyleDisplay *parentDisplay; aParentFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)parentDisplay); if (parentDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_ROW_GROUP) { @@ -1758,7 +1779,9 @@ nsCSSFrameConstructor::TableIsValidCellContent(nsIPresContext* aPresContext, #ifdef INCLUDE_XUL if ( (nsXULAtoms::button == tag.get()) || - (nsXULAtoms::titledbutton == tag.get()) || + (nsXULAtoms::titledbutton == tag.get()) || + (nsXULAtoms::grippy == tag.get()) || + (nsXULAtoms::splitter == tag.get()) || (nsXULAtoms::checkbox == tag.get()) || (nsXULAtoms::slider == tag.get()) || (nsXULAtoms::spinner == tag.get()) || @@ -2668,6 +2691,11 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext PR_TRUE, childItems); } + // if there are any anonymous children create frames for them + CreateAnonymousFrames(aPresContext, aTag, aState, aContent, newFrame, + childItems); + + // Set the frame's initial child list newFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList); @@ -2716,6 +2744,59 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext return rv; } +// after the node has been constructed and initialized create any +// anonymous content a node needs. +nsresult +nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresContext* aPresContext, + nsIAtom* aTag, + nsFrameConstructorState& aState, + nsIContent* aContent, + nsIFrame* aNewFrame, + nsFrameItems& aChildItems) +{ + + // only these tags types can have anonymous content. We do this check for performance + // reasons. If we did a query interface on every tag it would be very inefficient. + if (aTag != nsHTMLAtoms::input && + aTag != nsXULAtoms::slider && + aTag != nsXULAtoms::splitter && + aTag != nsXULAtoms::scrollbar) { + return NS_OK; + + } + + + nsCOMPtr creator(do_QueryInterface(aNewFrame)); + + if (!creator) + return NS_OK; + + // see if the frame implements anonymous content + nsCOMPtr anonymousItems; + NS_NewISupportsArray(getter_AddRefs(anonymousItems)); + + creator->CreateAnonymousContent(*anonymousItems); + + PRUint32 count = 0; + anonymousItems->Count(&count); + + for (PRUint32 i=0; i < count; i++) + { + // get our child's content and set its parent to our content + nsCOMPtr node; + anonymousItems->GetElementAt(i,getter_AddRefs(node)); + + nsCOMPtr content(do_QueryInterface(node)); + content->SetParent(aContent); + + // create the frame and attach it to our frame + ConstructFrame(aPresContext, aState, content, aNewFrame, PR_FALSE, aChildItems); + } + + return NS_OK; +} + + #ifdef INCLUDE_XUL nsresult nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext, @@ -2939,6 +3020,22 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext, rv = NS_NewTitledButtonFrame(&newFrame); } // End of THUMB CONSTRUCTION logic + + // SPLITTER CONSTRUCTION + else if (aTag == nsXULAtoms::splitter) { + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewSplitterFrame(&newFrame); + } + // End of SPLITTER CONSTRUCTION logic + + // GRIPPY CONSTRUCTION + else if (aTag == nsXULAtoms::grippy) { + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewGrippyFrame(&newFrame); + } + // End of GRIPPY CONSTRUCTION logic } // If we succeeded in creating a frame then initialize it, process its @@ -2971,9 +3068,9 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext, childItems); } - // if any anonymous nodes need to be created create them. - CreateAnonymousXULContent(aPresContext, aTag, aState, aContent, newFrame, - childItems); + // if there are any anonymous children create frames for them + CreateAnonymousFrames(aPresContext, aTag, aState, aContent, newFrame, + childItems); // Set the frame's initial child list newFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList); @@ -3000,117 +3097,6 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext, return rv; } -// after the node has been constructed create any -// anonymous content a node needs. -nsresult -nsCSSFrameConstructor::CreateAnonymousXULContent(nsIPresContext* aPresContext, - nsIAtom* aTag, - nsFrameConstructorState& aState, - nsIContent* aContent, - nsIFrame* aParentFrame, - nsFrameItems& aChildItems) -{ - if (aTag == nsXULAtoms::treechildren) { - // See if our parent is a tree. - nsCOMPtr grandPappy; - aContent->GetParent(*getter_AddRefs(grandPappy)); - nsCOMPtr tag; - grandPappy->GetTag(*getter_AddRefs(tag)); - nsCOMPtr element = do_QueryInterface(grandPappy); - nsString mode; - element->GetAttribute("mode", mode); - if (tag.get() == nsXULAtoms::tree) { - // We will want to have a scrollbar. - ((nsTreeRowGroupFrame*)aParentFrame)->SetFrameConstructor(this); - ((nsTreeRowGroupFrame*)aParentFrame)->SetShouldHaveScrollbar(); - } - } - - // if we are creating a scrollbar - if (aTag == nsXULAtoms::scrollbar) { - - // if we have no children create anonymous ones - PRInt32 count; - aContent->ChildCount(count); - - if (count == 0) - { - // get the document - nsCOMPtr idocument; - aContent->GetDocument(*getter_AddRefs(idocument)); - - nsCOMPtr document(do_QueryInterface(idocument)); - - // create a decrement button - nsCOMPtr node; - document->CreateElement("scrollbarbutton",getter_AddRefs(node)); - nsCOMPtr content; - //content->SetNameSpaceID(nsXULAtoms::nameSpaceID); - - content = do_QueryInterface(node); - content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::kClass, "decrement", PR_TRUE); - content->SetParent(aContent); - - ConstructFrame(aPresContext, aState, content, aParentFrame, PR_FALSE, aChildItems); - - // a slider - document->CreateElement("slider",getter_AddRefs(node)); - content = do_QueryInterface(node); - content->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "100%", PR_TRUE); - content->SetParent(aContent); - - ConstructFrame(aPresContext, aState, content, aParentFrame, PR_FALSE, aChildItems); - - // make sure the slider's thumb is flexible. - nsIFrame* thumb; - aChildItems.lastChild->FirstChild(nsnull,&thumb); - nsCOMPtr thumbContent; - thumb->GetContent(getter_AddRefs(thumbContent)); - - // make sure we got it - nsIAtom* tag = nsnull; - thumbContent->GetTag(tag); - NS_ASSERTION(tag == nsXULAtoms::thumb, "Could not get slider while creating scrollbar!"); - - thumbContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "100%", PR_TRUE); - - - // and increment button - document->CreateElement("scrollbarbutton",getter_AddRefs(node)); - content = do_QueryInterface(node); - content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::kClass, "increment", PR_TRUE); - content->SetParent(aContent); - - ConstructFrame(aPresContext, aState, content, aParentFrame, PR_FALSE, aChildItems); - } - } else if (aTag == nsXULAtoms::slider) { - - // if we have not children create anonymous ones - PRInt32 count; - aContent->ChildCount(count); - - if (count == 0) - { - // get the document - nsCOMPtr idocument; - aContent->GetDocument(*getter_AddRefs(idocument)); - - nsCOMPtr document(do_QueryInterface(idocument)); - - // create a thumb - nsCOMPtr node; - document->CreateElement("thumb",getter_AddRefs(node)); - nsCOMPtr content; - content = do_QueryInterface(node); - - ConstructFrame(aPresContext, aState, content, aParentFrame, PR_FALSE, aChildItems); - } - } - - return NS_OK; -} - - #endif nsresult diff --git a/mozilla/layout/base/nsCSSFrameConstructor.h b/mozilla/layout/base/nsCSSFrameConstructor.h index 04f3d004cce..06599768b9b 100644 --- a/mozilla/layout/base/nsCSSFrameConstructor.h +++ b/mozilla/layout/base/nsCSSFrameConstructor.h @@ -416,6 +416,14 @@ protected: nsIStyleContext* aStyleContext, nsFrameItems& aFrameItems); + nsresult CreateAnonymousFrames(nsIPresContext* aPresContext, + nsIAtom* aTag, + nsFrameConstructorState& aState, + nsIContent* aContent, + nsIFrame* aNewFrame, + nsFrameItems& aChildItems); + + #ifdef INCLUDE_XUL nsresult ConstructXULFrame(nsIPresContext* aPresContext, nsFrameConstructorState& aState, @@ -426,13 +434,6 @@ protected: nsFrameItems& aFrameItems, PRBool& aHaltProcessing); - nsresult CreateAnonymousXULContent(nsIPresContext* aPresContext, - nsIAtom* aTag, - nsFrameConstructorState& aState, - nsIContent* aContent, - nsIFrame* aParentFrame, - nsFrameItems& aChildItems); - #endif nsresult ConstructFrameByDisplayType(nsIPresContext* aPresContext, diff --git a/mozilla/layout/forms/nsFileControlFrame.cpp b/mozilla/layout/forms/nsFileControlFrame.cpp index 52e884a8595..b851e9005de 100644 --- a/mozilla/layout/forms/nsFileControlFrame.cpp +++ b/mozilla/layout/forms/nsFileControlFrame.cpp @@ -38,14 +38,20 @@ #include "nsINameSpaceManager.h" #include "nsCOMPtr.h" #include "nsFileSpec.h" +#include "nsISupportsArray.h" +#include "nsIDOMElement.h" +#include "nsIDOMDocument.h" +#include "nsDocument.h" +#include "nsIDOMMouseListener.h" + -// XXX make this pixels -#define CONTROL_SPACING 40 static NS_DEFINE_IID(kCFileWidgetCID, NS_FILEWIDGET_CID); static NS_DEFINE_IID(kIFileWidgetIID, NS_IFILEWIDGET_IID); static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID); static NS_DEFINE_IID(kIDOMHTMLInputElementIID, NS_IDOMHTMLINPUTELEMENT_IID); +static NS_DEFINE_IID(kIDOMMouseListenerIID, NS_IDOMMOUSELISTENER_IID); +static NS_DEFINE_IID(kIAnonymousContentCreatorIID, NS_IANONYMOUS_CONTENT_CREATOR_IID); nsresult NS_NewFileControlFrame(nsIFrame** aNewFrame) @@ -54,7 +60,7 @@ NS_NewFileControlFrame(nsIFrame** aNewFrame) if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsFileControlFrame* it = new nsFileControlFrame; + nsFileControlFrame* it = new nsFileControlFrame(); if (!it) { return NS_ERROR_OUT_OF_MEMORY; } @@ -62,12 +68,38 @@ NS_NewFileControlFrame(nsIFrame** aNewFrame) return NS_OK; } -nsFileControlFrame::nsFileControlFrame() - : nsHTMLContainerFrame() +nsFileControlFrame::nsFileControlFrame():mTextFrame(nsnull), mFormFrame(nsnull) { - mTextFrame = nsnull; - mBrowseFrame = nsnull; - mFormFrame = nsnull; +} + +NS_IMETHODIMP +nsFileControlFrame::CreateAnonymousContent(nsISupportsArray& aChildList) +{ + + // create text field + nsIHTMLContent* text = nsnull; + nsIAtom* tag = NS_NewAtom("input"); + NS_NewHTMLInputElement(&text, tag); + text->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::type, nsAutoString("text"), PR_FALSE); + aChildList.AppendElement(text); + + // create browse button + nsIHTMLContent* browse = nsnull; + tag = NS_NewAtom("input"); + NS_NewHTMLInputElement(&browse, tag); + browse->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::type, nsAutoString("button"), PR_FALSE); + browse->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, nsAutoString("browse..."), PR_FALSE); + aChildList.AppendElement(browse); + + // get the reciever interface from the browser button's content node + nsCOMPtr reciever(do_QueryInterface(browse)); + + // we shouldn't have to unregister this listener because when + // our frame goes away all these content node go away as well + // because our frame is the only one who references them. + reciever->AddEventListenerByIID(this, kIDOMMouseListenerIID); + + return NS_OK; } nsresult @@ -76,11 +108,19 @@ nsFileControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) NS_PRECONDITION(0 != aInstancePtr, "null ptr"); if (NULL == aInstancePtr) { return NS_ERROR_NULL_POINTER; - } - if (aIID.Equals(kIFormControlFrameIID)) { + } else if (aIID.Equals(kIAnonymousContentCreatorIID)) { + *aInstancePtr = (void*)(nsIAnonymousContentCreator*) this; + NS_ADDREF_THIS(); + return NS_OK; + } else if (aIID.Equals(kIFormControlFrameIID)) { *aInstancePtr = (void*) ((nsIFormControlFrame*) this); return NS_OK; - } + } else if (aIID.Equals(kIDOMMouseListenerIID)) { + *aInstancePtr = (void*)(nsIDOMMouseListener*) this; + NS_ADDREF_THIS(); + return NS_OK; + } + return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr); } @@ -133,14 +173,16 @@ nsFileControlFrame::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 -void nsFileControlFrame::MouseClicked(nsIPresContext* aPresContext) +/** + * This is called when our browse button is clicked + */ +nsresult +nsFileControlFrame::MouseClick(nsIDOMEvent* aMouseEvent) { nsIView* textView; mTextFrame->GetView(&textView); if (nsnull == textView) { - return; + return NS_OK; } nsresult result = NS_OK; @@ -174,6 +216,8 @@ void nsFileControlFrame::MouseClicked(nsIPresContext* aPresContext) NS_RELEASE(fileWidget); } NS_RELEASE(parentWidget); + + return NS_OK; } @@ -182,114 +226,67 @@ NS_IMETHODIMP nsFileControlFrame::Reflow(nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { - // add ourself as an nsIFormControlFrame - if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { + if (mFormFrame == nsnull && eReflowReason_Initial == aReflowState.reason) { + // add ourself as an nsIFormControlFrame nsFormFrame::AddFormControlFrame(aPresContext, *this); + mTextFrame = GetTextControlFrame(this); } - PRInt32 numChildren = mFrames.GetLength(); - - nsIFrame* childFrame; - if (0 == numChildren) { - // XXX This code should move to Init(), someday when the frame construction - // changes are all done and Init() is always getting called... - PRBool disabled = nsFormFrame::GetDisabled(this); - nsIHTMLContent* text = nsnull; - nsIAtom* tag = NS_NewAtom("text"); - NS_NewHTMLInputElement(&text, tag); - text->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::type, nsAutoString("text"), PR_FALSE); - if (disabled) { - text->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::disabled, nsAutoString("1"), PR_FALSE); // XXX this should use an "empty" bool value + return nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); +} + +/* +NS_IMETHODIMP +nsFileControlFrame::SetInitialChildList(nsIPresContext& aPresContext, + nsIAtom* aListName, + nsIFrame* aChildList) +{ + nsresult r = nsAreaFrame::SetInitialChildList(aPresContext, aListName, aChildList); + + // given that the CSS frame constuctor created all our frames. We need to find the text field + // so we can get info from it. + mTextFrame = GetTextControlFrame(this); +} +*/ + +/** + * Given a start node. Find the given text node inside. We need to do this because the + * frame constuctor create the frame and its implementation. So we are given the text + * node from the constructor and we find it in our tree. + */ +nsTextControlFrame* +nsFileControlFrame::GetTextControlFrame(nsIFrame* aStart) +{ + // find the text control frame. + nsIFrame* childFrame = nsnull; + aStart->FirstChild(nsnull, &childFrame); + + while (nsnull != childFrame) + { + // see if the child is a text control + nsCOMPtr content; + childFrame->GetContent(getter_AddRefs(content)); + nsIAtom* atom; + if (content->GetTag(atom) == NS_OK && atom == nsHTMLAtoms::input) { + nsString value; + + if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::type, value)) + { + if (value == "text") + return (nsTextControlFrame*)childFrame; + } } - // XXX: hard-wired for the native text control frame - // construction of the text control should happen in nsCSSFrameConstruction - NS_NewNativeTextControlFrame(&childFrame); - - //XXX: This style should be cached, rather than resolved each time. - // Get pseudo style for the text field - nsCOMPtr textFieldStyleContext; - nsresult rv = aPresContext.ResolvePseudoStyleContextFor(mContent, nsHTMLAtoms::fileTextStylePseudo, - mStyleContext, PR_FALSE, - getter_AddRefs(textFieldStyleContext)); - - if (NS_SUCCEEDED(rv)) { - // Found the pseudo style for the text field - childFrame->Init(aPresContext, text, this, textFieldStyleContext, nsnull); - } else { - // Can't find pseduo style so use the style set for the file updload element - childFrame->Init(aPresContext, mContent, this, mStyleContext, nsnull); - } - mTextFrame = (nsTextControlFrame*)childFrame; - mFrames.SetFrames(childFrame); - - nsIHTMLContent* browse = nsnull; - tag = NS_NewAtom("browse"); - NS_NewHTMLInputElement(&browse, tag); - browse->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::type, nsAutoString("browse"), PR_FALSE); - if (disabled) { - browse->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::disabled, nsAutoString("1"), PR_FALSE); // XXX should be "empty" - } - NS_NewButtonControlFrame(&childFrame); - ((nsButtonControlFrame*)childFrame)->SetMouseListener((nsIFormControlFrame*)this); - mBrowseFrame = (nsButtonControlFrame*)childFrame; - - //XXX: This style should be cached, rather than resolved each time. - // Get pseudo style for the button - nsCOMPtr buttonStyleContext; - rv = aPresContext.ResolvePseudoStyleContextFor(mContent, nsHTMLAtoms::fileButtonStylePseudo, - mStyleContext, PR_FALSE, - getter_AddRefs(buttonStyleContext)); - if (NS_SUCCEEDED(rv)) { - // Found pseduo style for the button - childFrame->Init(aPresContext, browse, this, buttonStyleContext, nsnull); - } else { - // Can't find pseudo style for the button so use the style set for the file upload element - childFrame->Init(aPresContext, mContent, this, mStyleContext, nsnull); - } - - mFrames.FirstChild()->SetNextSibling(childFrame); - - NS_RELEASE(text); - NS_RELEASE(browse); + // if not continue looking + nsTextControlFrame* frame = GetTextControlFrame(childFrame); + if (frame != nsnull) + return frame; + + nsresult rv = childFrame->GetNextSibling(&childFrame); + NS_ASSERTION(rv == NS_OK,"failed to get next child"); } - nsSize maxSize(aReflowState.availableWidth, aReflowState.availableHeight); - nsHTMLReflowMetrics desiredSize = aDesiredSize; - aDesiredSize.width = CONTROL_SPACING; - aDesiredSize.height = 0; - childFrame = mFrames.FirstChild(); - nsPoint offset(0,0); - while (nsnull != childFrame) { // reflow, place, size the children - nsHTMLReflowState reflowState(aPresContext, aReflowState, childFrame, - maxSize); - nsIHTMLReflow* htmlReflow; - - if (NS_OK == childFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) { - htmlReflow->WillReflow(aPresContext); - htmlReflow->Reflow(aPresContext, desiredSize, reflowState, aStatus); - NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); - nsRect rect(offset.x, offset.y, desiredSize.width, desiredSize.height); - childFrame->SetRect(rect); - maxSize.width -= desiredSize.width; - aDesiredSize.width += desiredSize.width; - aDesiredSize.height = desiredSize.height; - childFrame->GetNextSibling(&childFrame); - offset.x += desiredSize.width + CONTROL_SPACING; - } - } - - aDesiredSize.ascent = aDesiredSize.height; - aDesiredSize.descent = 0; - - if (nsnull != aDesiredSize.maxElementSize) { -//XXX aDesiredSize.AddBorderPaddingToMaxElementSize(borderPadding); - aDesiredSize.maxElementSize->width = aDesiredSize.width; - aDesiredSize.maxElementSize->height = aDesiredSize.height; - } - - aStatus = NS_FRAME_COMPLETE; - return NS_OK; + return nsnull; } PRIntn @@ -439,41 +436,5 @@ nsFileControlFrame::Paint(nsIPresContext& aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { -#ifndef XP_MAC -// XXX: This is temporary until we can find out whats going wrong on the MAC -// where widget's are not being created in presentation shell 0. - - // Since the file control has a mTextFrame which does not live in - // the content model it is necessary to get the current text value - // from the nsFileControlFrame through the content model, then - // explicitly ask the test frame to draw it. The mTextFrame's Paint - // method will still be called, but it will not render the current - // contents because it will not be possible for the content - // associated with the mTextFrame to get a handle to it frame in the - // presentation shell 0. - - // Only paint if it doesn't have a widget. - if (HasWidget()) - return NS_OK; - - - nsAutoString browse("Browse..."); - nsRect rect; - mBrowseFrame->GetRect(rect); - mBrowseFrame->PaintButton(aPresContext, aRenderingContext, aDirtyRect, - browse, rect); - - - mTextFrame->PaintTextControlBackground(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); - - if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { - nsString text; - if (NS_SUCCEEDED(nsFormControlHelper::GetInputElementValue(mContent, &text, PR_FALSE))) { - nsRect rect; - mTextFrame->GetRect(rect); - mTextFrame->PaintTextControl(aPresContext, aRenderingContext, aDirtyRect, text, mStyleContext, rect); - } - } -#endif - return NS_OK; + return nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); } diff --git a/mozilla/layout/forms/nsFileControlFrame.h b/mozilla/layout/forms/nsFileControlFrame.h index 53846054fdc..ad04d5611a8 100644 --- a/mozilla/layout/forms/nsFileControlFrame.h +++ b/mozilla/layout/forms/nsFileControlFrame.h @@ -19,18 +19,29 @@ #ifndef nsFileControlFrame_h___ #define nsFileControlFrame_h___ -#include "nsHTMLContainerFrame.h" +#include "nsAreaFrame.h" #include "nsIFormControlFrame.h" +#include "nsIDOMMouseListener.h" +#include "nsIAnonymousContentCreator.h" + class nsButtonControlFrame; class nsTextControlFrame; class nsFormFrame; +class nsISupportsArray; + +class nsFileControlFrame : public nsAreaFrame, + public nsIFormControlFrame, + public nsIDOMMouseListener, + public nsIAnonymousContentCreator -class nsFileControlFrame : public nsHTMLContainerFrame, - public nsIFormControlFrame { public: nsFileControlFrame(); + virtual void MouseClicked(nsIPresContext* aPresContext) {} + virtual void SetFormFrame(nsFormFrame* aFormFrame) { mFormFrame = aFormFrame; } + virtual nsFormFrame* GetFromFrame() { return mFormFrame; } + NS_IMETHOD Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, @@ -54,14 +65,7 @@ public: virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, nsString* aValues, nsString* aNames); - nsTextControlFrame* GetTextFrame() { return mTextFrame; } - - void SetTextFrame(nsTextControlFrame* aFrame) { mTextFrame = aFrame; } - - nsButtonControlFrame* GetBrowseFrame() { return mBrowseFrame; } - void SetBrowseFrame(nsButtonControlFrame* aFrame) { mBrowseFrame = aFrame; } NS_IMETHOD GetName(nsString* aName); - virtual void SetFormFrame(nsFormFrame* aFormFrame) { mFormFrame = aFormFrame; } virtual PRBool IsSuccessful(nsIFormControlFrame* aSubmitter); virtual void Reset(); NS_IMETHOD GetType(PRInt32* aType) const; @@ -83,20 +87,68 @@ public: PRBool HasWidget(); - // nsIFormMouseListener - virtual void MouseClicked(nsIPresContext* aPresContext); + // from nsIAnonymousContentCreator + NS_IMETHOD CreateAnonymousContent(nsISupportsArray& aChildList); + // mouse events when out browse button is pressed + /** + * Processes a mouse down event + * @param aMouseEvent @see nsIDOMEvent.h + * @returns whether the event was consumed or ignored. @see nsresult + */ + virtual nsresult MouseDown(nsIDOMEvent* aMouseEvent) { return NS_OK; } + + /** + * Processes a mouse up event + * @param aMouseEvent @see nsIDOMEvent.h + * @returns whether the event was consumed or ignored. @see nsresult + */ + virtual nsresult MouseUp(nsIDOMEvent* aMouseEvent) { return NS_OK; } + + /** + * Processes a mouse click event + * @param aMouseEvent @see nsIDOMEvent.h + * @returns whether the event was consumed or ignored. @see nsresult + * + */ + virtual nsresult MouseClick(nsIDOMEvent* aMouseEvent); // we only care when the button is clicked + + /** + * Processes a mouse click event + * @param aMouseEvent @see nsIDOMEvent.h + * @returns whether the event was consumed or ignored. @see nsresult + * + */ + virtual nsresult MouseDblClick(nsIDOMEvent* aMouseEvent) { return NS_OK; } + + /** + * Processes a mouse enter event + * @param aMouseEvent @see nsIDOMEvent.h + * @returns whether the event was consumed or ignored. @see nsresult + */ + virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent) { return NS_OK; } + + /** + * Processes a mouse leave event + * @param aMouseEvent @see nsIDOMEvent.h + * @returns whether the event was consumed or ignored. @see nsresult + */ + virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent) { return NS_OK; } + + virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; } + protected: nsIWidget* GetWindowTemp(nsIView *aView); // XXX temporary virtual PRIntn GetSkipSides() const; nsTextControlFrame* mTextFrame; - nsButtonControlFrame* mBrowseFrame; - nsFormFrame* mFormFrame; + nsFormFrame* mFormFrame; private: + nsTextControlFrame* GetTextControlFrame(nsIFrame* aStart); + NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; } NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; } }; diff --git a/mozilla/layout/generic/nsIAnonymousContentCreator.h b/mozilla/layout/generic/nsIAnonymousContentCreator.h new file mode 100644 index 00000000000..06165ca4111 --- /dev/null +++ b/mozilla/layout/generic/nsIAnonymousContentCreator.h @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + + +#ifndef nsIAnonymousContentCreator_h___ +#define nsIAnonymousContentCreator_h___ + +#include "nsISupports.h" +class nsISupportsArray; + +// {41a69e00-2d6d-11d3-b033-a1357139787c} +#define NS_IANONYMOUS_CONTENT_CREATOR_IID { 0x41a69e00, 0x2d6d, 0x11d3, { 0xb0, 0x33, 0xa1, 0x35, 0x71, 0x39, 0x78, 0x7c } } + + +/** + * Any source for anonymous content can implement this interface to provide it. + * HTML frames like nsFileControlFrame currently use this as well as XUL frames + * like nsScrollbarFrame & nsSliderFrame. + */ +class nsIAnonymousContentCreator : public nsISupports { +public: + static const nsIID& GetIID() { static nsIID iid = NS_IANONYMOUS_CONTENT_CREATOR_IID; return iid; } + NS_IMETHOD CreateAnonymousContent(nsISupportsArray& aAnonymousItems)=0; +}; + + +#endif + diff --git a/mozilla/layout/html/base/src/nsIAnonymousContentCreator.h b/mozilla/layout/html/base/src/nsIAnonymousContentCreator.h new file mode 100644 index 00000000000..06165ca4111 --- /dev/null +++ b/mozilla/layout/html/base/src/nsIAnonymousContentCreator.h @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + + +#ifndef nsIAnonymousContentCreator_h___ +#define nsIAnonymousContentCreator_h___ + +#include "nsISupports.h" +class nsISupportsArray; + +// {41a69e00-2d6d-11d3-b033-a1357139787c} +#define NS_IANONYMOUS_CONTENT_CREATOR_IID { 0x41a69e00, 0x2d6d, 0x11d3, { 0xb0, 0x33, 0xa1, 0x35, 0x71, 0x39, 0x78, 0x7c } } + + +/** + * Any source for anonymous content can implement this interface to provide it. + * HTML frames like nsFileControlFrame currently use this as well as XUL frames + * like nsScrollbarFrame & nsSliderFrame. + */ +class nsIAnonymousContentCreator : public nsISupports { +public: + static const nsIID& GetIID() { static nsIID iid = NS_IANONYMOUS_CONTENT_CREATOR_IID; return iid; } + NS_IMETHOD CreateAnonymousContent(nsISupportsArray& aAnonymousItems)=0; +}; + + +#endif + diff --git a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp index 52e884a8595..b851e9005de 100644 --- a/mozilla/layout/html/forms/src/nsFileControlFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFileControlFrame.cpp @@ -38,14 +38,20 @@ #include "nsINameSpaceManager.h" #include "nsCOMPtr.h" #include "nsFileSpec.h" +#include "nsISupportsArray.h" +#include "nsIDOMElement.h" +#include "nsIDOMDocument.h" +#include "nsDocument.h" +#include "nsIDOMMouseListener.h" + -// XXX make this pixels -#define CONTROL_SPACING 40 static NS_DEFINE_IID(kCFileWidgetCID, NS_FILEWIDGET_CID); static NS_DEFINE_IID(kIFileWidgetIID, NS_IFILEWIDGET_IID); static NS_DEFINE_IID(kIFormControlFrameIID, NS_IFORMCONTROLFRAME_IID); static NS_DEFINE_IID(kIDOMHTMLInputElementIID, NS_IDOMHTMLINPUTELEMENT_IID); +static NS_DEFINE_IID(kIDOMMouseListenerIID, NS_IDOMMOUSELISTENER_IID); +static NS_DEFINE_IID(kIAnonymousContentCreatorIID, NS_IANONYMOUS_CONTENT_CREATOR_IID); nsresult NS_NewFileControlFrame(nsIFrame** aNewFrame) @@ -54,7 +60,7 @@ NS_NewFileControlFrame(nsIFrame** aNewFrame) if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsFileControlFrame* it = new nsFileControlFrame; + nsFileControlFrame* it = new nsFileControlFrame(); if (!it) { return NS_ERROR_OUT_OF_MEMORY; } @@ -62,12 +68,38 @@ NS_NewFileControlFrame(nsIFrame** aNewFrame) return NS_OK; } -nsFileControlFrame::nsFileControlFrame() - : nsHTMLContainerFrame() +nsFileControlFrame::nsFileControlFrame():mTextFrame(nsnull), mFormFrame(nsnull) { - mTextFrame = nsnull; - mBrowseFrame = nsnull; - mFormFrame = nsnull; +} + +NS_IMETHODIMP +nsFileControlFrame::CreateAnonymousContent(nsISupportsArray& aChildList) +{ + + // create text field + nsIHTMLContent* text = nsnull; + nsIAtom* tag = NS_NewAtom("input"); + NS_NewHTMLInputElement(&text, tag); + text->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::type, nsAutoString("text"), PR_FALSE); + aChildList.AppendElement(text); + + // create browse button + nsIHTMLContent* browse = nsnull; + tag = NS_NewAtom("input"); + NS_NewHTMLInputElement(&browse, tag); + browse->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::type, nsAutoString("button"), PR_FALSE); + browse->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::value, nsAutoString("browse..."), PR_FALSE); + aChildList.AppendElement(browse); + + // get the reciever interface from the browser button's content node + nsCOMPtr reciever(do_QueryInterface(browse)); + + // we shouldn't have to unregister this listener because when + // our frame goes away all these content node go away as well + // because our frame is the only one who references them. + reciever->AddEventListenerByIID(this, kIDOMMouseListenerIID); + + return NS_OK; } nsresult @@ -76,11 +108,19 @@ nsFileControlFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) NS_PRECONDITION(0 != aInstancePtr, "null ptr"); if (NULL == aInstancePtr) { return NS_ERROR_NULL_POINTER; - } - if (aIID.Equals(kIFormControlFrameIID)) { + } else if (aIID.Equals(kIAnonymousContentCreatorIID)) { + *aInstancePtr = (void*)(nsIAnonymousContentCreator*) this; + NS_ADDREF_THIS(); + return NS_OK; + } else if (aIID.Equals(kIFormControlFrameIID)) { *aInstancePtr = (void*) ((nsIFormControlFrame*) this); return NS_OK; - } + } else if (aIID.Equals(kIDOMMouseListenerIID)) { + *aInstancePtr = (void*)(nsIDOMMouseListener*) this; + NS_ADDREF_THIS(); + return NS_OK; + } + return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr); } @@ -133,14 +173,16 @@ nsFileControlFrame::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 -void nsFileControlFrame::MouseClicked(nsIPresContext* aPresContext) +/** + * This is called when our browse button is clicked + */ +nsresult +nsFileControlFrame::MouseClick(nsIDOMEvent* aMouseEvent) { nsIView* textView; mTextFrame->GetView(&textView); if (nsnull == textView) { - return; + return NS_OK; } nsresult result = NS_OK; @@ -174,6 +216,8 @@ void nsFileControlFrame::MouseClicked(nsIPresContext* aPresContext) NS_RELEASE(fileWidget); } NS_RELEASE(parentWidget); + + return NS_OK; } @@ -182,114 +226,67 @@ NS_IMETHODIMP nsFileControlFrame::Reflow(nsIPresContext& aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus) { - // add ourself as an nsIFormControlFrame - if (!mFormFrame && (eReflowReason_Initial == aReflowState.reason)) { + if (mFormFrame == nsnull && eReflowReason_Initial == aReflowState.reason) { + // add ourself as an nsIFormControlFrame nsFormFrame::AddFormControlFrame(aPresContext, *this); + mTextFrame = GetTextControlFrame(this); } - PRInt32 numChildren = mFrames.GetLength(); - - nsIFrame* childFrame; - if (0 == numChildren) { - // XXX This code should move to Init(), someday when the frame construction - // changes are all done and Init() is always getting called... - PRBool disabled = nsFormFrame::GetDisabled(this); - nsIHTMLContent* text = nsnull; - nsIAtom* tag = NS_NewAtom("text"); - NS_NewHTMLInputElement(&text, tag); - text->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::type, nsAutoString("text"), PR_FALSE); - if (disabled) { - text->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::disabled, nsAutoString("1"), PR_FALSE); // XXX this should use an "empty" bool value + return nsAreaFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); +} + +/* +NS_IMETHODIMP +nsFileControlFrame::SetInitialChildList(nsIPresContext& aPresContext, + nsIAtom* aListName, + nsIFrame* aChildList) +{ + nsresult r = nsAreaFrame::SetInitialChildList(aPresContext, aListName, aChildList); + + // given that the CSS frame constuctor created all our frames. We need to find the text field + // so we can get info from it. + mTextFrame = GetTextControlFrame(this); +} +*/ + +/** + * Given a start node. Find the given text node inside. We need to do this because the + * frame constuctor create the frame and its implementation. So we are given the text + * node from the constructor and we find it in our tree. + */ +nsTextControlFrame* +nsFileControlFrame::GetTextControlFrame(nsIFrame* aStart) +{ + // find the text control frame. + nsIFrame* childFrame = nsnull; + aStart->FirstChild(nsnull, &childFrame); + + while (nsnull != childFrame) + { + // see if the child is a text control + nsCOMPtr content; + childFrame->GetContent(getter_AddRefs(content)); + nsIAtom* atom; + if (content->GetTag(atom) == NS_OK && atom == nsHTMLAtoms::input) { + nsString value; + + if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::type, value)) + { + if (value == "text") + return (nsTextControlFrame*)childFrame; + } } - // XXX: hard-wired for the native text control frame - // construction of the text control should happen in nsCSSFrameConstruction - NS_NewNativeTextControlFrame(&childFrame); - - //XXX: This style should be cached, rather than resolved each time. - // Get pseudo style for the text field - nsCOMPtr textFieldStyleContext; - nsresult rv = aPresContext.ResolvePseudoStyleContextFor(mContent, nsHTMLAtoms::fileTextStylePseudo, - mStyleContext, PR_FALSE, - getter_AddRefs(textFieldStyleContext)); - - if (NS_SUCCEEDED(rv)) { - // Found the pseudo style for the text field - childFrame->Init(aPresContext, text, this, textFieldStyleContext, nsnull); - } else { - // Can't find pseduo style so use the style set for the file updload element - childFrame->Init(aPresContext, mContent, this, mStyleContext, nsnull); - } - mTextFrame = (nsTextControlFrame*)childFrame; - mFrames.SetFrames(childFrame); - - nsIHTMLContent* browse = nsnull; - tag = NS_NewAtom("browse"); - NS_NewHTMLInputElement(&browse, tag); - browse->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::type, nsAutoString("browse"), PR_FALSE); - if (disabled) { - browse->SetAttribute(kNameSpaceID_HTML, nsHTMLAtoms::disabled, nsAutoString("1"), PR_FALSE); // XXX should be "empty" - } - NS_NewButtonControlFrame(&childFrame); - ((nsButtonControlFrame*)childFrame)->SetMouseListener((nsIFormControlFrame*)this); - mBrowseFrame = (nsButtonControlFrame*)childFrame; - - //XXX: This style should be cached, rather than resolved each time. - // Get pseudo style for the button - nsCOMPtr buttonStyleContext; - rv = aPresContext.ResolvePseudoStyleContextFor(mContent, nsHTMLAtoms::fileButtonStylePseudo, - mStyleContext, PR_FALSE, - getter_AddRefs(buttonStyleContext)); - if (NS_SUCCEEDED(rv)) { - // Found pseduo style for the button - childFrame->Init(aPresContext, browse, this, buttonStyleContext, nsnull); - } else { - // Can't find pseudo style for the button so use the style set for the file upload element - childFrame->Init(aPresContext, mContent, this, mStyleContext, nsnull); - } - - mFrames.FirstChild()->SetNextSibling(childFrame); - - NS_RELEASE(text); - NS_RELEASE(browse); + // if not continue looking + nsTextControlFrame* frame = GetTextControlFrame(childFrame); + if (frame != nsnull) + return frame; + + nsresult rv = childFrame->GetNextSibling(&childFrame); + NS_ASSERTION(rv == NS_OK,"failed to get next child"); } - nsSize maxSize(aReflowState.availableWidth, aReflowState.availableHeight); - nsHTMLReflowMetrics desiredSize = aDesiredSize; - aDesiredSize.width = CONTROL_SPACING; - aDesiredSize.height = 0; - childFrame = mFrames.FirstChild(); - nsPoint offset(0,0); - while (nsnull != childFrame) { // reflow, place, size the children - nsHTMLReflowState reflowState(aPresContext, aReflowState, childFrame, - maxSize); - nsIHTMLReflow* htmlReflow; - - if (NS_OK == childFrame->QueryInterface(kIHTMLReflowIID, (void**)&htmlReflow)) { - htmlReflow->WillReflow(aPresContext); - htmlReflow->Reflow(aPresContext, desiredSize, reflowState, aStatus); - NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); - nsRect rect(offset.x, offset.y, desiredSize.width, desiredSize.height); - childFrame->SetRect(rect); - maxSize.width -= desiredSize.width; - aDesiredSize.width += desiredSize.width; - aDesiredSize.height = desiredSize.height; - childFrame->GetNextSibling(&childFrame); - offset.x += desiredSize.width + CONTROL_SPACING; - } - } - - aDesiredSize.ascent = aDesiredSize.height; - aDesiredSize.descent = 0; - - if (nsnull != aDesiredSize.maxElementSize) { -//XXX aDesiredSize.AddBorderPaddingToMaxElementSize(borderPadding); - aDesiredSize.maxElementSize->width = aDesiredSize.width; - aDesiredSize.maxElementSize->height = aDesiredSize.height; - } - - aStatus = NS_FRAME_COMPLETE; - return NS_OK; + return nsnull; } PRIntn @@ -439,41 +436,5 @@ nsFileControlFrame::Paint(nsIPresContext& aPresContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer) { -#ifndef XP_MAC -// XXX: This is temporary until we can find out whats going wrong on the MAC -// where widget's are not being created in presentation shell 0. - - // Since the file control has a mTextFrame which does not live in - // the content model it is necessary to get the current text value - // from the nsFileControlFrame through the content model, then - // explicitly ask the test frame to draw it. The mTextFrame's Paint - // method will still be called, but it will not render the current - // contents because it will not be possible for the content - // associated with the mTextFrame to get a handle to it frame in the - // presentation shell 0. - - // Only paint if it doesn't have a widget. - if (HasWidget()) - return NS_OK; - - - nsAutoString browse("Browse..."); - nsRect rect; - mBrowseFrame->GetRect(rect); - mBrowseFrame->PaintButton(aPresContext, aRenderingContext, aDirtyRect, - browse, rect); - - - mTextFrame->PaintTextControlBackground(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); - - if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer) { - nsString text; - if (NS_SUCCEEDED(nsFormControlHelper::GetInputElementValue(mContent, &text, PR_FALSE))) { - nsRect rect; - mTextFrame->GetRect(rect); - mTextFrame->PaintTextControl(aPresContext, aRenderingContext, aDirtyRect, text, mStyleContext, rect); - } - } -#endif - return NS_OK; + return nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); } diff --git a/mozilla/layout/html/forms/src/nsFileControlFrame.h b/mozilla/layout/html/forms/src/nsFileControlFrame.h index 53846054fdc..ad04d5611a8 100644 --- a/mozilla/layout/html/forms/src/nsFileControlFrame.h +++ b/mozilla/layout/html/forms/src/nsFileControlFrame.h @@ -19,18 +19,29 @@ #ifndef nsFileControlFrame_h___ #define nsFileControlFrame_h___ -#include "nsHTMLContainerFrame.h" +#include "nsAreaFrame.h" #include "nsIFormControlFrame.h" +#include "nsIDOMMouseListener.h" +#include "nsIAnonymousContentCreator.h" + class nsButtonControlFrame; class nsTextControlFrame; class nsFormFrame; +class nsISupportsArray; + +class nsFileControlFrame : public nsAreaFrame, + public nsIFormControlFrame, + public nsIDOMMouseListener, + public nsIAnonymousContentCreator -class nsFileControlFrame : public nsHTMLContainerFrame, - public nsIFormControlFrame { public: nsFileControlFrame(); + virtual void MouseClicked(nsIPresContext* aPresContext) {} + virtual void SetFormFrame(nsFormFrame* aFormFrame) { mFormFrame = aFormFrame; } + virtual nsFormFrame* GetFromFrame() { return mFormFrame; } + NS_IMETHOD Paint(nsIPresContext& aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, @@ -54,14 +65,7 @@ public: virtual PRBool GetNamesValues(PRInt32 aMaxNumValues, PRInt32& aNumValues, nsString* aValues, nsString* aNames); - nsTextControlFrame* GetTextFrame() { return mTextFrame; } - - void SetTextFrame(nsTextControlFrame* aFrame) { mTextFrame = aFrame; } - - nsButtonControlFrame* GetBrowseFrame() { return mBrowseFrame; } - void SetBrowseFrame(nsButtonControlFrame* aFrame) { mBrowseFrame = aFrame; } NS_IMETHOD GetName(nsString* aName); - virtual void SetFormFrame(nsFormFrame* aFormFrame) { mFormFrame = aFormFrame; } virtual PRBool IsSuccessful(nsIFormControlFrame* aSubmitter); virtual void Reset(); NS_IMETHOD GetType(PRInt32* aType) const; @@ -83,20 +87,68 @@ public: PRBool HasWidget(); - // nsIFormMouseListener - virtual void MouseClicked(nsIPresContext* aPresContext); + // from nsIAnonymousContentCreator + NS_IMETHOD CreateAnonymousContent(nsISupportsArray& aChildList); + // mouse events when out browse button is pressed + /** + * Processes a mouse down event + * @param aMouseEvent @see nsIDOMEvent.h + * @returns whether the event was consumed or ignored. @see nsresult + */ + virtual nsresult MouseDown(nsIDOMEvent* aMouseEvent) { return NS_OK; } + + /** + * Processes a mouse up event + * @param aMouseEvent @see nsIDOMEvent.h + * @returns whether the event was consumed or ignored. @see nsresult + */ + virtual nsresult MouseUp(nsIDOMEvent* aMouseEvent) { return NS_OK; } + + /** + * Processes a mouse click event + * @param aMouseEvent @see nsIDOMEvent.h + * @returns whether the event was consumed or ignored. @see nsresult + * + */ + virtual nsresult MouseClick(nsIDOMEvent* aMouseEvent); // we only care when the button is clicked + + /** + * Processes a mouse click event + * @param aMouseEvent @see nsIDOMEvent.h + * @returns whether the event was consumed or ignored. @see nsresult + * + */ + virtual nsresult MouseDblClick(nsIDOMEvent* aMouseEvent) { return NS_OK; } + + /** + * Processes a mouse enter event + * @param aMouseEvent @see nsIDOMEvent.h + * @returns whether the event was consumed or ignored. @see nsresult + */ + virtual nsresult MouseOver(nsIDOMEvent* aMouseEvent) { return NS_OK; } + + /** + * Processes a mouse leave event + * @param aMouseEvent @see nsIDOMEvent.h + * @returns whether the event was consumed or ignored. @see nsresult + */ + virtual nsresult MouseOut(nsIDOMEvent* aMouseEvent) { return NS_OK; } + + virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; } + protected: nsIWidget* GetWindowTemp(nsIView *aView); // XXX temporary virtual PRIntn GetSkipSides() const; nsTextControlFrame* mTextFrame; - nsButtonControlFrame* mBrowseFrame; - nsFormFrame* mFormFrame; + nsFormFrame* mFormFrame; private: + nsTextControlFrame* GetTextControlFrame(nsIFrame* aStart); + NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; } NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; } }; diff --git a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp index 6ba277873b9..412313ba447 100644 --- a/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/mozilla/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -61,6 +61,8 @@ #include "nsCSSAtoms.h" #include "nsIDeviceContext.h" #include "nsTextFragment.h" +#include "nsISupportsArray.h" +#include "nsIAnonymousContentCreator.h" #ifdef INCLUDE_XUL #include "nsXULAtoms.h" @@ -74,7 +76,6 @@ #include "nsIDOMDocument.h" #include "nsDocument.h" - nsresult NS_NewTabFrame ( nsIFrame** aNewFrame ); @@ -114,6 +115,11 @@ NS_NewScrollbarButtonFrame ( nsIFrame** aNewFrame ); nsresult NS_NewScrollbarFrame ( nsIFrame** aNewFrame ); +nsresult +NS_NewGrippyFrame ( nsIFrame** aNewFrame ); + +nsresult +NS_NewSplitterFrame ( nsIFrame** aNewFrame ); #endif //static NS_DEFINE_IID(kIStyleRuleIID, NS_ISTYLE_RULE_IID); @@ -1275,11 +1281,26 @@ nsCSSFrameConstructor::ConstructTableGroupFrameOnly(nsIPresContext* aPr // Create some anonymous extras within the tree body. if (aTableCreator.IsTreeCreator()) { - nsCOMPtr tag; - aContent->GetTag(*getter_AddRefs(tag)); - CreateAnonymousXULContent(aPresContext, tag, aState, aContent, aNewGroupFrame, - childItems); - + // BEGIN ANONYMOUS + // See if our parent is a tree. + nsCOMPtr tag; + aContent->GetTag(*getter_AddRefs(tag)); + + if (tag == nsXULAtoms::treechildren) { + // See if our parent is a tree. + nsCOMPtr grandPappy; + aContent->GetParent(*getter_AddRefs(grandPappy)); + grandPappy->GetTag(*getter_AddRefs(tag)); + nsCOMPtr element = do_QueryInterface(grandPappy); + nsString mode; + element->GetAttribute("mode", mode); + if (tag.get() == nsXULAtoms::tree) { + // We will want to have a scrollbar. + ((nsTreeRowGroupFrame*)aParentFrame)->SetFrameConstructor(this); + ((nsTreeRowGroupFrame*)aParentFrame)->SetShouldHaveScrollbar(); + } + } + // END ANONYMOUS const nsStyleDisplay *parentDisplay; aParentFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)parentDisplay); if (parentDisplay->mDisplay == NS_STYLE_DISPLAY_TABLE_ROW_GROUP) { @@ -1758,7 +1779,9 @@ nsCSSFrameConstructor::TableIsValidCellContent(nsIPresContext* aPresContext, #ifdef INCLUDE_XUL if ( (nsXULAtoms::button == tag.get()) || - (nsXULAtoms::titledbutton == tag.get()) || + (nsXULAtoms::titledbutton == tag.get()) || + (nsXULAtoms::grippy == tag.get()) || + (nsXULAtoms::splitter == tag.get()) || (nsXULAtoms::checkbox == tag.get()) || (nsXULAtoms::slider == tag.get()) || (nsXULAtoms::spinner == tag.get()) || @@ -2668,6 +2691,11 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext PR_TRUE, childItems); } + // if there are any anonymous children create frames for them + CreateAnonymousFrames(aPresContext, aTag, aState, aContent, newFrame, + childItems); + + // Set the frame's initial child list newFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList); @@ -2716,6 +2744,59 @@ nsCSSFrameConstructor::ConstructFrameByTag(nsIPresContext* aPresContext return rv; } +// after the node has been constructed and initialized create any +// anonymous content a node needs. +nsresult +nsCSSFrameConstructor::CreateAnonymousFrames(nsIPresContext* aPresContext, + nsIAtom* aTag, + nsFrameConstructorState& aState, + nsIContent* aContent, + nsIFrame* aNewFrame, + nsFrameItems& aChildItems) +{ + + // only these tags types can have anonymous content. We do this check for performance + // reasons. If we did a query interface on every tag it would be very inefficient. + if (aTag != nsHTMLAtoms::input && + aTag != nsXULAtoms::slider && + aTag != nsXULAtoms::splitter && + aTag != nsXULAtoms::scrollbar) { + return NS_OK; + + } + + + nsCOMPtr creator(do_QueryInterface(aNewFrame)); + + if (!creator) + return NS_OK; + + // see if the frame implements anonymous content + nsCOMPtr anonymousItems; + NS_NewISupportsArray(getter_AddRefs(anonymousItems)); + + creator->CreateAnonymousContent(*anonymousItems); + + PRUint32 count = 0; + anonymousItems->Count(&count); + + for (PRUint32 i=0; i < count; i++) + { + // get our child's content and set its parent to our content + nsCOMPtr node; + anonymousItems->GetElementAt(i,getter_AddRefs(node)); + + nsCOMPtr content(do_QueryInterface(node)); + content->SetParent(aContent); + + // create the frame and attach it to our frame + ConstructFrame(aPresContext, aState, content, aNewFrame, PR_FALSE, aChildItems); + } + + return NS_OK; +} + + #ifdef INCLUDE_XUL nsresult nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext, @@ -2939,6 +3020,22 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext, rv = NS_NewTitledButtonFrame(&newFrame); } // End of THUMB CONSTRUCTION logic + + // SPLITTER CONSTRUCTION + else if (aTag == nsXULAtoms::splitter) { + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewSplitterFrame(&newFrame); + } + // End of SPLITTER CONSTRUCTION logic + + // GRIPPY CONSTRUCTION + else if (aTag == nsXULAtoms::grippy) { + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewGrippyFrame(&newFrame); + } + // End of GRIPPY CONSTRUCTION logic } // If we succeeded in creating a frame then initialize it, process its @@ -2971,9 +3068,9 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext, childItems); } - // if any anonymous nodes need to be created create them. - CreateAnonymousXULContent(aPresContext, aTag, aState, aContent, newFrame, - childItems); + // if there are any anonymous children create frames for them + CreateAnonymousFrames(aPresContext, aTag, aState, aContent, newFrame, + childItems); // Set the frame's initial child list newFrame->SetInitialChildList(*aPresContext, nsnull, childItems.childList); @@ -3000,117 +3097,6 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext, return rv; } -// after the node has been constructed create any -// anonymous content a node needs. -nsresult -nsCSSFrameConstructor::CreateAnonymousXULContent(nsIPresContext* aPresContext, - nsIAtom* aTag, - nsFrameConstructorState& aState, - nsIContent* aContent, - nsIFrame* aParentFrame, - nsFrameItems& aChildItems) -{ - if (aTag == nsXULAtoms::treechildren) { - // See if our parent is a tree. - nsCOMPtr grandPappy; - aContent->GetParent(*getter_AddRefs(grandPappy)); - nsCOMPtr tag; - grandPappy->GetTag(*getter_AddRefs(tag)); - nsCOMPtr element = do_QueryInterface(grandPappy); - nsString mode; - element->GetAttribute("mode", mode); - if (tag.get() == nsXULAtoms::tree) { - // We will want to have a scrollbar. - ((nsTreeRowGroupFrame*)aParentFrame)->SetFrameConstructor(this); - ((nsTreeRowGroupFrame*)aParentFrame)->SetShouldHaveScrollbar(); - } - } - - // if we are creating a scrollbar - if (aTag == nsXULAtoms::scrollbar) { - - // if we have no children create anonymous ones - PRInt32 count; - aContent->ChildCount(count); - - if (count == 0) - { - // get the document - nsCOMPtr idocument; - aContent->GetDocument(*getter_AddRefs(idocument)); - - nsCOMPtr document(do_QueryInterface(idocument)); - - // create a decrement button - nsCOMPtr node; - document->CreateElement("scrollbarbutton",getter_AddRefs(node)); - nsCOMPtr content; - //content->SetNameSpaceID(nsXULAtoms::nameSpaceID); - - content = do_QueryInterface(node); - content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::kClass, "decrement", PR_TRUE); - content->SetParent(aContent); - - ConstructFrame(aPresContext, aState, content, aParentFrame, PR_FALSE, aChildItems); - - // a slider - document->CreateElement("slider",getter_AddRefs(node)); - content = do_QueryInterface(node); - content->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "100%", PR_TRUE); - content->SetParent(aContent); - - ConstructFrame(aPresContext, aState, content, aParentFrame, PR_FALSE, aChildItems); - - // make sure the slider's thumb is flexible. - nsIFrame* thumb; - aChildItems.lastChild->FirstChild(nsnull,&thumb); - nsCOMPtr thumbContent; - thumb->GetContent(getter_AddRefs(thumbContent)); - - // make sure we got it - nsIAtom* tag = nsnull; - thumbContent->GetTag(tag); - NS_ASSERTION(tag == nsXULAtoms::thumb, "Could not get slider while creating scrollbar!"); - - thumbContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "100%", PR_TRUE); - - - // and increment button - document->CreateElement("scrollbarbutton",getter_AddRefs(node)); - content = do_QueryInterface(node); - content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::kClass, "increment", PR_TRUE); - content->SetParent(aContent); - - ConstructFrame(aPresContext, aState, content, aParentFrame, PR_FALSE, aChildItems); - } - } else if (aTag == nsXULAtoms::slider) { - - // if we have not children create anonymous ones - PRInt32 count; - aContent->ChildCount(count); - - if (count == 0) - { - // get the document - nsCOMPtr idocument; - aContent->GetDocument(*getter_AddRefs(idocument)); - - nsCOMPtr document(do_QueryInterface(idocument)); - - // create a thumb - nsCOMPtr node; - document->CreateElement("thumb",getter_AddRefs(node)); - nsCOMPtr content; - content = do_QueryInterface(node); - - ConstructFrame(aPresContext, aState, content, aParentFrame, PR_FALSE, aChildItems); - } - } - - return NS_OK; -} - - #endif nsresult diff --git a/mozilla/layout/html/style/src/nsCSSFrameConstructor.h b/mozilla/layout/html/style/src/nsCSSFrameConstructor.h index 04f3d004cce..06599768b9b 100644 --- a/mozilla/layout/html/style/src/nsCSSFrameConstructor.h +++ b/mozilla/layout/html/style/src/nsCSSFrameConstructor.h @@ -416,6 +416,14 @@ protected: nsIStyleContext* aStyleContext, nsFrameItems& aFrameItems); + nsresult CreateAnonymousFrames(nsIPresContext* aPresContext, + nsIAtom* aTag, + nsFrameConstructorState& aState, + nsIContent* aContent, + nsIFrame* aNewFrame, + nsFrameItems& aChildItems); + + #ifdef INCLUDE_XUL nsresult ConstructXULFrame(nsIPresContext* aPresContext, nsFrameConstructorState& aState, @@ -426,13 +434,6 @@ protected: nsFrameItems& aFrameItems, PRBool& aHaltProcessing); - nsresult CreateAnonymousXULContent(nsIPresContext* aPresContext, - nsIAtom* aTag, - nsFrameConstructorState& aState, - nsIContent* aContent, - nsIFrame* aParentFrame, - nsFrameItems& aChildItems); - #endif nsresult ConstructFrameByDisplayType(nsIPresContext* aPresContext, diff --git a/mozilla/layout/xul/base/src/Makefile.in b/mozilla/layout/xul/base/src/Makefile.in index 67c1c0cab3c..b49f51efd59 100644 --- a/mozilla/layout/xul/base/src/Makefile.in +++ b/mozilla/layout/xul/base/src/Makefile.in @@ -36,6 +36,8 @@ LOCAL_INCLUDES = \ # Note the sophisticated alphabetical ordering :-| CPPSRCS = \ + nsSplitterFrame.cpp \ + nsGrippyFrame.cpp \ nsTabFrame.cpp \ nsDeckFrame.cpp \ nsBoxFrame.cpp \ diff --git a/mozilla/layout/xul/base/src/makefile.win b/mozilla/layout/xul/base/src/makefile.win index 4ecde986e1c..41673a6c0eb 100644 --- a/mozilla/layout/xul/base/src/makefile.win +++ b/mozilla/layout/xul/base/src/makefile.win @@ -24,6 +24,8 @@ REQUIRES=xpcom raptor pref DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN CPPSRCS= \ + nsSplitterFrame.cpp \ + nsGrippyFrame.cpp \ nsTabFrame.cpp \ nsDeckFrame.cpp \ nsBoxFrame.cpp \ @@ -45,6 +47,8 @@ CPPSRCS= \ $(NULL) CPP_OBJS= \ + .\$(OBJDIR)\nsGrippyFrame.obj \ + .\$(OBJDIR)\nsSplitterFrame.obj \ .\$(OBJDIR)\nsTabFrame.obj \ .\$(OBJDIR)\nsDeckFrame.obj \ .\$(OBJDIR)\nsBoxFrame.obj \ diff --git a/mozilla/layout/xul/base/src/nsBoxFrame.cpp b/mozilla/layout/xul/base/src/nsBoxFrame.cpp index dc611edad51..2a7d62cc23a 100644 --- a/mozilla/layout/xul/base/src/nsBoxFrame.cpp +++ b/mozilla/layout/xul/base/src/nsBoxFrame.cpp @@ -35,6 +35,7 @@ #include "nsXULAtoms.h" #include "nsIReflowCommand.h" #include "nsIContent.h" +#include "nsIViewManager.h" #define CONSTANT float(0.0) @@ -312,27 +313,29 @@ nsBoxFrame::FlowChildren(nsIPresContext& aPresContext, nsIFrame* childFrame = mFrames.FirstChild(); while (nsnull != childFrame) { + + if (!mSprings[count].collapsed) + { + // reflow only fixed children + if (mSprings[count].flex == 0.0) { + FlowChildAt(childFrame, aPresContext, aDesiredSize, aReflowState, aStatus, count, incrementalChild); - // reflow only fixed children - if (mSprings[count].flex == 0.0) { - FlowChildAt(childFrame, aPresContext, aDesiredSize, aReflowState, aStatus, count, incrementalChild); - - // if its height greater than the max. Set the max to this height and set a flag - // saying we will need to do another pass. But keep going there - // may be another child that is bigger - if (!mHorizontal) { - if (rect.height == NS_INTRINSICSIZE || aDesiredSize.height > mSprings[count].calculatedSize.height) { - mSprings[count].calculatedSize.height = aDesiredSize.height; - resized[count] = PR_TRUE; - } - } else { - if (rect.width == NS_INTRINSICSIZE || aDesiredSize.width > mSprings[count].calculatedSize.width) { - mSprings[count].calculatedSize.width = aDesiredSize.width; - resized[count] = PR_TRUE; - } + // if its height greater than the max. Set the max to this height and set a flag + // saying we will need to do another pass. But keep going there + // may be another child that is bigger + if (!mHorizontal) { + if (rect.height == NS_INTRINSICSIZE || aDesiredSize.height > mSprings[count].calculatedSize.height) { + mSprings[count].calculatedSize.height = aDesiredSize.height; + resized[count] = PR_TRUE; + } + } else { + if (rect.width == NS_INTRINSICSIZE || aDesiredSize.width > mSprings[count].calculatedSize.width) { + mSprings[count].calculatedSize.width = aDesiredSize.width; + resized[count] = PR_TRUE; + } + } } - } - + } nsresult rv = childFrame->GetNextSibling(&childFrame); NS_ASSERTION(rv == NS_OK,"failed to get next child"); count++; @@ -368,6 +371,8 @@ nsBoxFrame::FlowChildren(nsIPresContext& aPresContext, if (count == changedIndex) break; + if (!mSprings[count].collapsed) + { // reflow if the child needs it or we are on a second pass // if (mSprings[count].needsReflow || passes > 0) { FlowChildAt(childFrame, aPresContext, aDesiredSize, aReflowState, aStatus, count, incrementalChild); @@ -424,6 +429,7 @@ nsBoxFrame::FlowChildren(nsIPresContext& aPresContext, changedIndex = count; } } + } nsresult rv = childFrame->GetNextSibling(&childFrame); NS_ASSERTION(rv == NS_OK,"failed to get next child"); @@ -448,6 +454,29 @@ nsBoxFrame::FlowChildren(nsIPresContext& aPresContext, return NS_OK; } +/* +void CollapseChildren(nsIFrame* frame) +{ + nsIFrame* childFrame = mFrames.FirstChild(); + nscoord count = 0; + while (nsnull != childFrame) + { + childFrame->SetRect(nsRect(0,0,0,0)); + // make the view really small as well + nsIView* view = nsnull; + childFrame->GetView(&view); + + if (view) { + view->SetDimensions(0,0,PR_FALSE); + } + + CollapseChildren(childFrame); + rv = childFrame->GetNextSibling(&childFrame); + NS_ASSERTION(rv == NS_OK,"failed to get next child"); + } +} +*/ + /** * Given the boxes rect. Set the x,y locations of all its children. Taking into account * their margins @@ -463,43 +492,61 @@ nsBoxFrame::PlaceChildren(nsRect& boxRect) nscoord count = 0; while (nsnull != childFrame) { - const nsStyleSpacing* spacing; - nsresult rv = childFrame->GetStyleData(eStyleStruct_Spacing, - (const nsStyleStruct*&) spacing); + nsresult rv; - nsMargin margin(0,0,0,0); - spacing->GetMargin(margin); + // make collapsed children not show up + if (mSprings[count].collapsed) { + childFrame->SetRect(nsRect(0,0,0,0)); - if (mHorizontal) { - x += margin.left; - y = boxRect.y + margin.top; + // make the view really small as well + nsIView* view = nsnull; + childFrame->GetView(&view); + + if (view) { + nsCOMPtr vm; + view->GetViewManager(*getter_AddRefs(vm)); + vm->ResizeView(view, 0,0); + } } else { - y += margin.top; - x = boxRect.x + margin.left; - } + const nsStyleSpacing* spacing; + rv = childFrame->GetStyleData(eStyleStruct_Spacing, + (const nsStyleStruct*&) spacing); - nsRect rect; - childFrame->GetRect(rect); - rect.x = x; - rect.y = y; - childFrame->SetRect(rect); + nsMargin margin(0,0,0,0); + spacing->GetMargin(margin); - // add in the right margin - if (mHorizontal) - x += margin.right; - else - y += margin.bottom; + if (mHorizontal) { + x += margin.left; + y = boxRect.y + margin.top; + } else { + y += margin.top; + x = boxRect.x + margin.left; + } + + nsRect rect; + childFrame->GetRect(rect); + rect.x = x; + rect.y = y; + childFrame->SetRect(rect); + + // add in the right margin + if (mHorizontal) + x += margin.right; + else + y += margin.bottom; - if (mHorizontal) { - x += rect.width; - //width += rect.width + margin.left + margin.right; - } else { - y += rect.height; - //height += rect.height + margin.top + margin.bottom; + if (mHorizontal) { + x += rect.width; + //width += rect.width + margin.left + margin.right; + } else { + y += rect.height; + //height += rect.height + margin.top + margin.bottom; + } } rv = childFrame->GetNextSibling(&childFrame); NS_ASSERTION(rv == NS_OK,"failed to get next child"); + count++; } return NS_OK; @@ -754,6 +801,10 @@ nsBoxFrame::LayoutChildrenInRect(nsRect& size) for (i=0; iGetStyleData(eStyleStruct_Spacing, - (const nsStyleStruct*&) spacing); + // see if the child is collapsed + const nsStyleDisplay* disp; + childFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)disp)); - NS_ASSERTION(rv == NS_OK,"failed to get spacing info"); - if (NS_FAILED(rv)) - return rv; + // if collapsed then the child will have no size + if (disp->mVisible == NS_STYLE_VISIBILITY_COLLAPSE) + mSprings[count].collapsed = PR_TRUE; + else { + // add in the child's margin and border/padding if there is one. + const nsStyleSpacing* spacing; + nsresult rv = childFrame->GetStyleData(eStyleStruct_Spacing, + (const nsStyleStruct*&) spacing); - nsMargin margin; - spacing->GetMargin(margin); - nsSize m(margin.left+margin.right,margin.top+margin.bottom); - mSprings[count].minSize += m; - mSprings[count].prefSize += m; + NS_ASSERTION(rv == NS_OK,"failed to get spacing info"); + if (NS_FAILED(rv)) + return rv; - spacing->GetBorderPadding(margin); - nsSize b(margin.left+margin.right,margin.top+margin.bottom); - mSprings[count].minSize += b; - mSprings[count].prefSize += b; + nsMargin margin; + spacing->GetMargin(margin); + nsSize m(margin.left+margin.right,margin.top+margin.bottom); + mSprings[count].minSize += m; + mSprings[count].prefSize += m; + + spacing->GetBorderPadding(margin); + nsSize b(margin.left+margin.right,margin.top+margin.bottom); + mSprings[count].minSize += b; + mSprings[count].prefSize += b; + } // ok we don't need to calc this guy again mSprings[count].needsRecalc = PR_FALSE; @@ -1088,32 +1153,6 @@ nsBoxFrame::Release(void) return NS_OK; } - -/* -nsBoxInfo::nsBoxInfo() -{ - clear(); -} - -void -nsBoxInfo::clear() -{ - prefSize.width = 0; - prefSize.height = 0; - - minSize.width = 0; - minSize.height = 0; - - flex = 0.0; - - maxSize.width = NS_INTRINSICSIZE; - maxSize.height = NS_INTRINSICSIZE; - - prefWidthIntrinsic = PR_FALSE; - prefHeightIntrinsic = PR_FALSE; -} -*/ - nsCalculatedBoxInfo::nsCalculatedBoxInfo() { clear(); @@ -1125,6 +1164,7 @@ nsCalculatedBoxInfo::clear() nsBoxInfo::clear(); needsReflow = PR_TRUE; needsRecalc = PR_TRUE; + collapsed = PR_FALSE; calculatedSize.width = 0; calculatedSize.height = 0; diff --git a/mozilla/layout/xul/base/src/nsBoxFrame.h b/mozilla/layout/xul/base/src/nsBoxFrame.h index 2b85427773f..bde5adce0ec 100644 --- a/mozilla/layout/xul/base/src/nsBoxFrame.h +++ b/mozilla/layout/xul/base/src/nsBoxFrame.h @@ -38,6 +38,7 @@ public: PRBool sizeValid; PRBool needsReflow; PRBool needsRecalc; + PRBool collapsed; nsCalculatedBoxInfo(); virtual void clear(); diff --git a/mozilla/layout/xul/base/src/nsGrippyFrame.cpp b/mozilla/layout/xul/base/src/nsGrippyFrame.cpp new file mode 100644 index 00000000000..7b1ea227ceb --- /dev/null +++ b/mozilla/layout/xul/base/src/nsGrippyFrame.cpp @@ -0,0 +1,201 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +// +// Eric Vaughan +// Netscape Communications +// +// See documentation in associated header file +// + +#include "nsGrippyFrame.h" +#include "nsScrollbarButtonFrame.h" +#include "nsIStyleContext.h" +#include "nsIPresContext.h" +#include "nsIContent.h" +#include "nsCOMPtr.h" +#include "nsHTMLIIDs.h" +#include "nsUnitConversion.h" +#include "nsINameSpaceManager.h" +#include "nsHTMLAtoms.h" +#include "nsXULAtoms.h" +#include "nsIReflowCommand.h" +#include "nsSliderFrame.h" +#include "nsIDOMElement.h" +#include "nsIDOMDocument.h" +#include "nsDocument.h" + +// +// NS_NewToolbarFrame +// +// Creates a new Toolbar frame and returns it in |aNewFrame| +// +nsresult +NS_NewGrippyFrame ( nsIFrame** aNewFrame ) +{ + NS_PRECONDITION(aNewFrame, "null OUT ptr"); + if (nsnull == aNewFrame) { + return NS_ERROR_NULL_POINTER; + } + nsGrippyFrame* it = new nsGrippyFrame; + if (nsnull == it) + return NS_ERROR_OUT_OF_MEMORY; + + *aNewFrame = it; + return NS_OK; + +} // NS_NewGrippyFrame + +nsGrippyFrame::nsGrippyFrame():mCollapsed(PR_FALSE) +{ +} + +void +nsGrippyFrame::MouseClicked(nsIPresContext& aPresContext) +{ + + nsString style; + + if (mCollapsed) { + style = mCollapsedChildStyle; + } else { + // when clicked see if we are in a splitter. + nsIFrame* splitter; + nsScrollbarButtonFrame::GetParentWithTag(nsXULAtoms::splitter, this, splitter); + + if (splitter == nsnull) + return; + + // get the splitters content node + nsCOMPtr content; + splitter->GetContent(getter_AddRefs(content)); + + // get the collapse attribute. If the attribute is not set collapse + // the child before otherwise collapse the child after + PRBool before = PR_TRUE; + nsString value; + if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsXULAtoms::collapse, value)) + { + if (value=="after") + before = PR_FALSE; + } + + // find the child just in the box just before the splitter. If we are not currently collapsed then + // then get the childs style attribute and store it. Then set the child style attribute to be display none. + // if we are already collapsed then set the child's style back to our stored value. + nsIFrame* child = GetChildBeforeAfter(splitter,before); + if (child == nsnull) + return; + + child->GetContent(getter_AddRefs(mCollapsedChild)); + + style = "visibility: collapse"; + mCollapsedChildStyle = ""; + mCollapsedChild->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::style, mCollapsedChildStyle); + } + + mCollapsedChild->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::style, style, PR_TRUE); + + mCollapsed = !mCollapsed; +} + +nsIFrame* +nsGrippyFrame::GetChildBeforeAfter(nsIFrame* start, PRBool before) +{ + nsIFrame* parent = nsnull; + start->GetParent(&parent); + PRInt32 index = IndexOf(parent,start); + PRInt32 count = CountFrames(parent); + + if (index == -1) + return nsnull; + + if (before) { + if (index == 0) { + return nsnull; + } + + return GetChildAt(parent, index-1); + } + + + if (index == count-1) + return nsnull; + + return GetChildAt(parent, index+1); + +} + +PRInt32 +nsGrippyFrame::IndexOf(nsIFrame* parent, nsIFrame* child) +{ + PRInt32 count = 0; + + nsIFrame* childFrame; + parent->FirstChild(nsnull, &childFrame); + while (nsnull != childFrame) + { + if (childFrame == child) + return count; + + nsresult rv = childFrame->GetNextSibling(&childFrame); + NS_ASSERTION(rv == NS_OK,"failed to get next child"); + count++; + } + + return -1; +} + +PRInt32 +nsGrippyFrame::CountFrames(nsIFrame* aFrame) +{ + PRInt32 count = 0; + + nsIFrame* childFrame; + aFrame->FirstChild(nsnull, &childFrame); + while (nsnull != childFrame) + { + nsresult rv = childFrame->GetNextSibling(&childFrame); + NS_ASSERTION(rv == NS_OK,"failed to get next child"); + count++; + } + + return count; +} + +nsIFrame* +nsGrippyFrame::GetChildAt(nsIFrame* parent, PRInt32 index) +{ + PRInt32 count = 0; + + nsIFrame* childFrame; + parent->FirstChild(nsnull, &childFrame); + while (nsnull != childFrame) + { + if (count == index) + return childFrame; + + nsresult rv = childFrame->GetNextSibling(&childFrame); + NS_ASSERTION(rv == NS_OK,"failed to get next child"); + count++; + } + + return nsnull; +} + diff --git a/mozilla/layout/xul/base/src/nsGrippyFrame.h b/mozilla/layout/xul/base/src/nsGrippyFrame.h new file mode 100644 index 00000000000..bf8f6462719 --- /dev/null +++ b/mozilla/layout/xul/base/src/nsGrippyFrame.h @@ -0,0 +1,57 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +/** + + Eric D Vaughan + This class lays out its children either vertically or horizontally + +**/ + +#ifndef nsGrippyFrame_h___ +#define nsGrippyFrame_h___ + +#include "nsTitledButtonFrame.h" +#include "nsCOMPtr.h" + +class nsGrippyFrame : public nsTitledButtonFrame +{ +public: + + friend nsresult NS_NewGrippyFrame(nsIFrame** aNewFrame); + + static nsIFrame* GetChildBeforeAfter(nsIFrame* start, PRBool before); + static nsIFrame* GetChildAt(nsIFrame* parent, PRInt32 index); + static PRInt32 IndexOf(nsIFrame* parent, nsIFrame* child); + static PRInt32 CountFrames(nsIFrame* aFrame); + nsGrippyFrame(); + +protected: + virtual void MouseClicked(nsIPresContext& aPresContext); + PRBool mCollapsed; + nsString mCollapsedChildStyle; + nsCOMPtr mCollapsedChild; + + +}; // class nsTabFrame + + + +#endif + diff --git a/mozilla/layout/xul/base/src/nsScrollbarFrame.cpp b/mozilla/layout/xul/base/src/nsScrollbarFrame.cpp index 6b624fb5ccc..4c9e65b68ef 100644 --- a/mozilla/layout/xul/base/src/nsScrollbarFrame.cpp +++ b/mozilla/layout/xul/base/src/nsScrollbarFrame.cpp @@ -27,6 +27,14 @@ #include "nsScrollbarFrame.h" #include "nsScrollbarButtonFrame.h" #include "nsXULAtoms.h" +#include "nsHTMLAtoms.h" +#include "nsISupportsArray.h" +#include "nsIDOMElement.h" +#include "nsIDOMDocument.h" +#include "nsDocument.h" +#include "nsINameSpaceManager.h" + +static NS_DEFINE_IID(kIAnonymousContentCreatorIID, NS_IANONYMOUS_CONTENT_CREATOR_IID); // // NS_NewToolbarFrame @@ -49,6 +57,48 @@ NS_NewScrollbarFrame ( nsIFrame** aNewFrame ) } // NS_NewScrollbarFrame +/** + * Anonymous interface + */ +NS_IMETHODIMP +nsScrollbarFrame::CreateAnonymousContent(nsISupportsArray& aAnonymousChildren) +{ + // if not content the create some anonymous content + PRInt32 count = 0; + mContent->ChildCount(count); + + if (count == 0) { + // get the document + nsCOMPtr idocument; + mContent->GetDocument(*getter_AddRefs(idocument)); + + nsCOMPtr document(do_QueryInterface(idocument)); + + // create a decrement button + nsCOMPtr node; + document->CreateElement("scrollbarbutton",getter_AddRefs(node)); + nsCOMPtr content; + + content = do_QueryInterface(node); + content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::kClass, "decrement", PR_TRUE); + aAnonymousChildren.AppendElement(content); + + // a slider + document->CreateElement("slider",getter_AddRefs(node)); + content = do_QueryInterface(node); + content->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "100%", PR_TRUE); + aAnonymousChildren.AppendElement(content); + + // and increment button + document->CreateElement("scrollbarbutton",getter_AddRefs(node)); + content = do_QueryInterface(node); + content->SetAttribute(kNameSpaceID_None, nsHTMLAtoms::kClass, "increment", PR_TRUE); + aAnonymousChildren.AppendElement(content); + } + + return NS_OK; +} + NS_IMETHODIMP nsScrollbarFrame::AttributeChanged(nsIPresContext* aPresContext, nsIContent* aChild, @@ -69,3 +119,21 @@ nsScrollbarFrame::AttributeChanged(nsIPresContext* aPresContext, return rv; } + +NS_IMETHODIMP +nsScrollbarFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (NULL == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + + *aInstancePtr = NULL; + + if (aIID.Equals(kIAnonymousContentCreatorIID)) { + *aInstancePtr = (void*)(nsIAnonymousContentCreator*) this; + NS_ADDREF_THIS(); + return NS_OK; + } + + return nsBoxFrame::QueryInterface(aIID, aInstancePtr); +} \ No newline at end of file diff --git a/mozilla/layout/xul/base/src/nsScrollbarFrame.h b/mozilla/layout/xul/base/src/nsScrollbarFrame.h index dab7d51fdfe..7421beb0fb5 100644 --- a/mozilla/layout/xul/base/src/nsScrollbarFrame.h +++ b/mozilla/layout/xul/base/src/nsScrollbarFrame.h @@ -25,10 +25,14 @@ #include "nsBoxFrame.h" +#include "nsIAnonymousContentCreator.h" + +class nsISupportsArray; nsresult NS_NewScrollbarFrame(nsIFrame** aResult) ; -class nsScrollbarFrame : public nsBoxFrame +class nsScrollbarFrame : public nsBoxFrame, + public nsIAnonymousContentCreator { public: nsScrollbarFrame() {} @@ -44,6 +48,12 @@ public: nsIAtom* aAttribute, PRInt32 aHint); + // nsIAnonymousConentCreator + NS_IMETHOD CreateAnonymousContent(nsISupportsArray& aAnonymousItems); + + NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); + NS_IMETHOD_(nsrefcnt) AddRef() { return NS_OK; } + NS_IMETHOD_(nsrefcnt) Release() { return NS_OK; } }; // class nsScrollbarFrame diff --git a/mozilla/layout/xul/base/src/nsSliderFrame.cpp b/mozilla/layout/xul/base/src/nsSliderFrame.cpp index 4759028f43c..5c446fa19df 100644 --- a/mozilla/layout/xul/base/src/nsSliderFrame.cpp +++ b/mozilla/layout/xul/base/src/nsSliderFrame.cpp @@ -49,15 +49,18 @@ #include "nsTitledButtonFrame.h" #include "nsScrollbarButtonFrame.h" #include "nsIScrollbarListener.h" +#include "nsISupportsArray.h" + +static NS_DEFINE_IID(kIAnonymousContentCreatorIID, NS_IANONYMOUS_CONTENT_CREATOR_IID); nsresult -NS_NewSliderFrame ( nsIFrame** aNewFrame ) +NS_NewSliderFrame ( nsIFrame** aNewFrame) { NS_PRECONDITION(aNewFrame, "null OUT ptr"); if (nsnull == aNewFrame) { return NS_ERROR_NULL_POINTER; } - nsSliderFrame* it = new nsSliderFrame; + nsSliderFrame* it = new nsSliderFrame(); if (nsnull == it) return NS_ERROR_OUT_OF_MEMORY; @@ -66,12 +69,47 @@ NS_NewSliderFrame ( nsIFrame** aNewFrame ) } // NS_NewSliderFrame - nsSliderFrame::nsSliderFrame() :mScrollbarListener(nsnull), mCurPos(0) { } +/** + * Anonymous interface + */ +NS_IMETHODIMP +nsSliderFrame::CreateAnonymousContent(nsISupportsArray& aAnonymousChildren) +{ + // supply anonymous content if there is no content + PRInt32 count = 0; + mContent->ChildCount(count); + if (count == 0) + { + // get the document + nsCOMPtr idocument; + mContent->GetDocument(*getter_AddRefs(idocument)); + + nsCOMPtr document(do_QueryInterface(idocument)); + + // create a thumb + nsCOMPtr node; + document->CreateElement("thumb",getter_AddRefs(node)); + nsCOMPtr content; + content = do_QueryInterface(node); + + // if we are not in a scrollbar default our thumbs flex to be + // flexible. + nsIContent* scrollbar = GetScrollBar(); + + if (scrollbar) + content->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "100%", PR_TRUE); + + aAnonymousChildren.AppendElement(content); + } + + return NS_OK; +} + NS_IMETHODIMP @@ -765,7 +803,11 @@ NS_IMETHODIMP nsSliderFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr) *aInstancePtr = NULL; - if (aIID.Equals(kIDOMMouseListenerIID)) { + if (aIID.Equals(kIAnonymousContentCreatorIID)) { + *aInstancePtr = (void*)(nsIAnonymousContentCreator*) this; + NS_ADDREF_THIS(); + return NS_OK; + } else if (aIID.Equals(kIDOMMouseListenerIID)) { *aInstancePtr = (void*)(nsIDOMMouseListener*) this; NS_ADDREF_THIS(); return NS_OK; diff --git a/mozilla/layout/xul/base/src/nsSliderFrame.h b/mozilla/layout/xul/base/src/nsSliderFrame.h index bbedb1ef651..94e685a7fa8 100644 --- a/mozilla/layout/xul/base/src/nsSliderFrame.h +++ b/mozilla/layout/xul/base/src/nsSliderFrame.h @@ -29,14 +29,18 @@ #include "nsIAtom.h" #include "nsCOMPtr.h" #include "nsIDOMMouseListener.h" +#include "nsIAnonymousContentCreator.h" class nsString; class nsIScrollbarListener; +class nsISupportsArray; nsresult NS_NewSliderFrame(nsIFrame** aResult) ; -class nsSliderFrame : public nsHTMLContainerFrame, public nsIDOMMouseListener +class nsSliderFrame : public nsHTMLContainerFrame, + nsIDOMMouseListener, + nsIAnonymousContentCreator { public: nsSliderFrame(); @@ -64,6 +68,8 @@ public: nsIStyleContext* aContext, nsIFrame* asPrevInFlow); + NS_IMETHOD CreateAnonymousContent(nsISupportsArray& aAnonymousItems); + NS_IMETHOD Reflow(nsIPresContext& aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, diff --git a/mozilla/layout/xul/base/src/nsSplitterFrame.cpp b/mozilla/layout/xul/base/src/nsSplitterFrame.cpp new file mode 100644 index 00000000000..9aefc2aa920 --- /dev/null +++ b/mozilla/layout/xul/base/src/nsSplitterFrame.cpp @@ -0,0 +1,173 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and limitations + * under the License. + * + * The Original Code is Mozilla Communicator client code. + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. Portions created by Netscape are Copyright (C) 1998 + * Netscape Communications Corporation. All Rights Reserved. + */ + +// +// Eric Vaughan +// Netscape Communications +// +// See documentation in associated header file +// + +#include "nsSplitterFrame.h" +#include "nsXULAtoms.h" +#include "nsHTMLAtoms.h" +#include "nsISupportsArray.h" +#include "nsIDOMElement.h" +#include "nsIDOMDocument.h" +#include "nsIXMLContent.h" +#include "nsDocument.h" +#include "nsINameSpaceManager.h" +#include "nsScrollbarButtonFrame.h" + +static NS_DEFINE_IID(kIAnonymousContentCreatorIID, NS_IANONYMOUS_CONTENT_CREATOR_IID); + +// +// NS_NewSplitterFrame +// +// Creates a new Toolbar frame and returns it in |aNewFrame| +// +nsresult +NS_NewSplitterFrame ( nsIFrame** aNewFrame ) +{ + NS_PRECONDITION(aNewFrame, "null OUT ptr"); + if (nsnull == aNewFrame) { + return NS_ERROR_NULL_POINTER; + } + nsSplitterFrame* it = new nsSplitterFrame; + if (nsnull == it) + return NS_ERROR_OUT_OF_MEMORY; + + *aNewFrame = it; + return NS_OK; + +} // NS_NewSplitterFrame + +/** + * Anonymous interface + */ +NS_IMETHODIMP +nsSplitterFrame::CreateAnonymousContent(nsISupportsArray& aAnonymousChildren) +{ + // if not content the create some anonymous content + PRInt32 count = 0; + mContent->ChildCount(count); + + if (count == 0) { + // get the document + nsCOMPtr idocument; + mContent->GetDocument(*getter_AddRefs(idocument)); + nsCOMPtr document(do_QueryInterface(idocument)); + + // create a spring + nsCOMPtr node; + document->CreateElement("spring",getter_AddRefs(node)); + nsCOMPtr content; + content = do_QueryInterface(node); + content->SetNameSpaceID(nsXULAtoms::nameSpaceID); + content->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "100%", PR_TRUE); + aAnonymousChildren.AppendElement(content); + + // a grippy + document->CreateElement("grippy",getter_AddRefs(node)); + content = do_QueryInterface(node); + content->SetNameSpaceID(nsXULAtoms::nameSpaceID); + aAnonymousChildren.AppendElement(content); + + // create a spring + document->CreateElement("spring",getter_AddRefs(node)); + content = do_QueryInterface(node); + content->SetNameSpaceID(nsXULAtoms::nameSpaceID); + content->SetAttribute(kNameSpaceID_None, nsXULAtoms::flex, "100%", PR_TRUE); + aAnonymousChildren.AppendElement(content); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsSplitterFrame::AttributeChanged(nsIPresContext* aPresContext, + nsIContent* aChild, + nsIAtom* aAttribute, + PRInt32 aHint) +{ + nsresult rv = nsBoxFrame::AttributeChanged(aPresContext, aChild, + aAttribute, aHint); + // if the alignment changed. Let the grippy know + if (aAttribute == nsHTMLAtoms::align) { + // tell the slider its attribute changed so it can + // update itself + nsIFrame* grippy = nsnull; + nsScrollbarButtonFrame::GetChildWithTag(nsXULAtoms::grippy, this, grippy); + if (grippy) + grippy->AttributeChanged(aPresContext, aChild, aAttribute, aHint); + } + + return rv; +} + +/** + * Initialize us. If we are in a box get our alignment so we know what direction we are + */ +NS_IMETHODIMP +nsSplitterFrame::Init(nsIPresContext& aPresContext, + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aContext, + nsIFrame* aPrevInFlow) +{ + nsresult rv = nsBoxFrame::Init(aPresContext, aContent, aParent, aContext, aPrevInFlow); + + // find the box we are in + nsIFrame* box = nsnull; + nsScrollbarButtonFrame::GetParentWithTag(nsXULAtoms::box, this, box); + + // see if the box is horizontal or vertical + if (box) { + nsCOMPtr content; + box->GetContent(getter_AddRefs(content)); + + nsString value; + content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, value); + if (value.EqualsIgnoreCase("vertical")) + mHorizontal = PR_TRUE; + else + mHorizontal = PR_FALSE; + } + + return rv; +} + +NS_IMETHODIMP +nsSplitterFrame::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (NULL == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + + *aInstancePtr = NULL; + + if (aIID.Equals(kIAnonymousContentCreatorIID)) { + *aInstancePtr = (void*)(nsIAnonymousContentCreator*) this; + NS_ADDREF_THIS(); + return NS_OK; + } + + return nsBoxFrame::QueryInterface(aIID, aInstancePtr); +} + diff --git a/mozilla/layout/xul/base/src/nsSplitterFrame.h b/mozilla/layout/xul/base/src/nsSplitterFrame.h new file mode 100644 index 00000000000..0323b26ebe2 --- /dev/null +++ b/mozilla/layout/xul/base/src/nsSplitterFrame.h @@ -0,0 +1,65 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +// +// nsSplitterFrame +// + +#ifndef nsSplitterFrame_h__ +#define nsSplitterFrame_h__ + + +#include "nsBoxFrame.h" +#include "nsIAnonymousContentCreator.h" + +class nsISupportsArray; + +nsresult NS_NewSplitterFrame(nsIFrame** aResult) ; + +class nsSplitterFrame : public nsBoxFrame, public nsIAnonymousContentCreator +{ +public: + nsSplitterFrame() {} + + // nsIFrame overrides + NS_IMETHOD GetFrameName(nsString& aResult) const { + return MakeFrameName("SplitterFrame", aResult); + } + + + NS_IMETHOD AttributeChanged(nsIPresContext* aPresContext, + nsIContent* aChild, + nsIAtom* aAttribute, + PRInt32 aHint); + + NS_IMETHOD Init(nsIPresContext& aPresContext, + nsIContent* aContent, + nsIFrame* aParent, + nsIStyleContext* aContext, + nsIFrame* aPrevInFlow); + + // nsIAnonymousContentCreator + NS_IMETHOD CreateAnonymousContent(nsISupportsArray& aAnonymousItems); + NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); + NS_IMETHOD_(nsrefcnt) AddRef(void) { return NS_OK; } + NS_IMETHOD_(nsrefcnt) Release(void) { return NS_OK; } + + +}; // class nsSplitterFrame + +#endif diff --git a/mozilla/layout/xul/content/src/nsXULAtoms.cpp b/mozilla/layout/xul/content/src/nsXULAtoms.cpp index 3d7fb4f7ae1..f3d947622a3 100644 --- a/mozilla/layout/xul/content/src/nsXULAtoms.cpp +++ b/mozilla/layout/xul/content/src/nsXULAtoms.cpp @@ -73,6 +73,9 @@ nsIAtom* nsXULAtoms::increment; nsIAtom* nsXULAtoms::pageincrement; nsIAtom* nsXULAtoms::thumb; nsIAtom* nsXULAtoms::toggled; +nsIAtom* nsXULAtoms::grippy; +nsIAtom* nsXULAtoms::splitter; +nsIAtom* nsXULAtoms::collapse; nsIAtom* nsXULAtoms::widget; nsIAtom* nsXULAtoms::window; @@ -140,6 +143,9 @@ void nsXULAtoms::AddrefAtoms() { pageincrement = NS_NewAtom("pageincrement"); thumb = NS_NewAtom("thumb"); toggled = NS_NewAtom("toggled"); + grippy = NS_NewAtom("grippy"); + splitter = NS_NewAtom("splitter"); + collapse = NS_NewAtom("collapse"); widget = NS_NewAtom("widget"); @@ -198,6 +204,9 @@ void nsXULAtoms::ReleaseAtoms() { NS_RELEASE(pageincrement); NS_RELEASE(thumb); NS_RELEASE(toggled); + NS_RELEASE(grippy); + NS_RELEASE(splitter); + NS_RELEASE(collapse); NS_RELEASE(widget); NS_RELEASE(window); diff --git a/mozilla/layout/xul/content/src/nsXULAtoms.h b/mozilla/layout/xul/content/src/nsXULAtoms.h index 32b517c1027..54c7bf2a462 100644 --- a/mozilla/layout/xul/content/src/nsXULAtoms.h +++ b/mozilla/layout/xul/content/src/nsXULAtoms.h @@ -95,6 +95,9 @@ public: static nsIAtom* thumb; static nsIAtom* toggled; + static nsIAtom* grippy; + static nsIAtom* splitter; + static nsIAtom* collapse; }; #endif /* nsXULAtoms_h___ */ diff --git a/mozilla/xpfe/AppCores/src/makefile.win b/mozilla/xpfe/AppCores/src/makefile.win index 545d130289d..baed13e28dd 100644 --- a/mozilla/xpfe/AppCores/src/makefile.win +++ b/mozilla/xpfe/AppCores/src/makefile.win @@ -176,8 +176,10 @@ install:: $(DLL) $(MAKE_INSTALL) ..\xul\resources\TB_NewStop.gif $(DIST)\bin\res\toolbar $(MAKE_INSTALL) ..\xul\resources\TB_NewHome.gif $(DIST)\bin\res\toolbar $(MAKE_INSTALL) ..\xul\resources\TB_NewPrint.gif $(DIST)\bin\res\toolbar - $(MAKE_INSTALL) ..\xul\resources\grippy.gif $(DIST)\bin\res\toolbar - $(MAKE_INSTALL) ..\xul\resources\grippyO.gif $(DIST)\bin\res\toolbar + $(MAKE_INSTALL) ..\xul\resources\grippy-horizontal-before.gif $(DIST)\bin\res\toolbar + $(MAKE_INSTALL) ..\xul\resources\grippy-horizontal-after.gif $(DIST)\bin\res\toolbar + $(MAKE_INSTALL) ..\xul\resources\grippy-vertical-before.gif $(DIST)\bin\res\toolbar + $(MAKE_INSTALL) ..\xul\resources\grippy-vertical-after.gif $(DIST)\bin\res\toolbar $(MAKE_INSTALL) ..\xul\resources\throbbingN.gif $(DIST)\bin\res\throbber @@ -260,8 +262,10 @@ clobber:: rm -f $(DIST)\bin\res\samples\TB_NewStop.gif rm -f $(DIST)\bin\res\samples\TB_NewHome.gif rm -f $(DIST)\bin\res\samples\TB_NewPrint.gif - rm -f $(DIST)\bin\res\toolbar\grippy.gif - rm -f $(DIST)\bin\res\toolbar\grippyO.gif + rm -f $(DIST)\bin\res\toolbar\grippy-horizontal-before.gif + rm -f $(DIST)\bin\res\toolbar\grippy-horizontal-after.gif + rm -f $(DIST)\bin\res\toolbar\grippy-vertical-before.gif + rm -f $(DIST)\bin\res\toolbar\grippy-vertical-after.gif rm -f $(DIST)\bin\res\throbber\throbbingN.gif diff --git a/mozilla/xpfe/AppCores/xul/Makefile.in b/mozilla/xpfe/AppCores/xul/Makefile.in index e75c90dfac5..2bf170f527e 100644 --- a/mozilla/xpfe/AppCores/xul/Makefile.in +++ b/mozilla/xpfe/AppCores/xul/Makefile.in @@ -96,8 +96,10 @@ EXPORT_RESOURCE_TOOLBAR = \ $(srcdir)/resources/TB_NewStop.gif \ $(srcdir)/resources/TB_NewHome.gif \ $(srcdir)/resources/TB_NewPrint.gif \ - $(srcdir)/resources/grippy.gif \ - $(srcdir)/resources/grippyO.gif \ + $(srcdir)/resources/grippy-horizontal-before.gif \ + $(srcdir)/resources/grippy-horizontal-after.gif \ + $(srcdir)/resources/grippy-vertical-before.gif \ + $(srcdir)/resources/grippy-vertical-after.gif \ $(NULL) EXPORT_RESOURCE_THROBBER = \ diff --git a/mozilla/xpfe/AppCores/xul/resources/grippy-horizontal-after.gif b/mozilla/xpfe/AppCores/xul/resources/grippy-horizontal-after.gif new file mode 100644 index 0000000000000000000000000000000000000000..71be69083efaa15f2b57c2a3a73929bec0353d48 GIT binary patch literal 157 zcmZ?wbhEHbWML>~*v!CSXqbHL*s=da1I3>#j0_Bn3_1)z05ZdY#mnFXLz=*~YqOsp zlT~d@+}0XDbJ5~kK?gLCZn{1(sqOllwb|wm&Zpm;*`az?ZCXufnE&&Q;!FJso!0nU WPfm-yrmww+wYYeN>UkkX25SIG3s$25 literal 0 HcmV?d00001 diff --git a/mozilla/xpfe/AppCores/xul/resources/grippy-horizontal-before.gif b/mozilla/xpfe/AppCores/xul/resources/grippy-horizontal-before.gif new file mode 100644 index 0000000000000000000000000000000000000000..6be9bc4f400a8649794f0e26a10d898af3dd3698 GIT binary patch literal 157 zcmZ?wbhEHbWML>~*v!CSXqbHL*s=da1I3>#j0_Bn3_1)z05ZdY#mnFX=aLx~R|+=Y znaf_K;@Y=7bkU+!jMA*jBUe#j0_Bn3_1)z05ZdY#m?XaL)Ki2*JpSC zPq-0zeFdYC*U~qyRuxF^FY>)#oR|J8B8kb#j0_Bn3_1)z05ZdY#n#{i=d!&Pug~uO zAHS7RC9`wI6t?Wu`*hwM`;v3|M`TxIC#O(?g9ndP`*EeBl{sqjeO45E8aA%Gv8L>F IF9U-$0KE=Rn*aa+ literal 0 HcmV?d00001 diff --git a/mozilla/xpfe/AppCores/xul/resources/grippy.gif b/mozilla/xpfe/AppCores/xul/resources/grippy.gif deleted file mode 100644 index 155352855c0c8f8441c0e52d575506595a1f8bac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 189 zcmZ?wbh9u|WM^<^_{_lY|NsB$>gw$5DcRZC$<=FBPK^AC#5U zt>zY_|F|>n((_MIIxH%?W_|XI-gIoLj&ZSQapeQgw{v@B&p%l=>E!YYmn+jst7S|T Y!?lG~6>U}3b(I{MMb#&I2r^g$0Al(>N&o-= diff --git a/mozilla/xpfe/AppCores/xul/resources/grippyO.gif b/mozilla/xpfe/AppCores/xul/resources/grippyO.gif deleted file mode 100644 index 1e73fba2af2ebfbb48e4c37366cb3409a433034d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 193 zcmZ?wbh9u|WM^<^_{_lY|NsAM*REApS7&EW$L=@LzEgPboXOUd8qY^-;)?EB+`hg^q^O}T e%2iG-m`$fkT~AX)RZEgVPsT!0e1@MOgEat-s6+Jt diff --git a/mozilla/xpfe/browser/src/xul.css b/mozilla/xpfe/browser/src/xul.css index 1a39a6c243b..3fc4574febd 100644 --- a/mozilla/xpfe/browser/src/xul.css +++ b/mozilla/xpfe/browser/src/xul.css @@ -931,4 +931,25 @@ treepusher.decrement:hover { treepusher.decrement[disabled="true"] { list-style-image: url(lessCols_dis.gif) -} \ No newline at end of file +} + +splitter { + display: block; +} + +grippy { + border: 1px outset white; + list-style-image: url(resource:/res/toolbar/grippy-horizontal-before.gif); + background-color: rgb(198,198,198); + display: block; + margin: 1px; +} + +box[align="vertical"] splitter[collapse="after"] grippy { + list-style-image: url(resource:/res/toolbar/grippy-vertical-after.gif); +} + +box splitter[collapse="after"] grippy { + list-style-image: url(resource:/res/toolbar/grippy-horizontal-after.gif); +} +