diff --git a/content/html/document/src/nsHTMLContentSink.cpp b/content/html/document/src/nsHTMLContentSink.cpp index 60747d3bfa40..3b858a886291 100644 --- a/content/html/document/src/nsHTMLContentSink.cpp +++ b/content/html/document/src/nsHTMLContentSink.cpp @@ -3011,7 +3011,7 @@ HTMLContentSink::StartLayout() if (mWebShell) { // initially show the scrollbars. We need to do this because another // document like a XUL document, could have have hidden the scrollbars. -EDV - mWebShell->SetScrolling(-1, PR_FALSE); + //mWebShell->SetScrolling(-1, PR_FALSE); if (mFrameset) { mWebShell->SetScrolling(NS_STYLE_OVERFLOW_HIDDEN, PR_FALSE); } diff --git a/content/shared/public/nsXULAtomList.h b/content/shared/public/nsXULAtomList.h index a80f46c6d89a..9b559c2b966b 100644 --- a/content/shared/public/nsXULAtomList.h +++ b/content/shared/public/nsXULAtomList.h @@ -99,6 +99,11 @@ XUL_ATOM(box, "box") XUL_ATOM(flex, "flex") XUL_ATOM(spring, "spring") XUL_ATOM(orient, "orient") +XUL_ATOM(autostretch, "autostretch") + +XUL_ATOM(titledbox, "titledbox") +XUL_ATOM(title, "title") +XUL_ATOM(titledboxContentPseudo, ":titledbox-content") XUL_ATOM(deck, "deck") XUL_ATOM(tabcontrol, "tabcontrol") diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index e5f9a979983f..226b6c46fdc8 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -74,9 +74,15 @@ #include "nsIAttributeContent.h" #include "nsIPref.h" #include "nsLegendFrame.h" +#include "nsTitleFrame.h" #include "nsIDOMWindow.h" #include "nsPIDOMWindow.h" +#ifdef INCLUDE_XUL +#include "nsIDOMXULCommandDispatcher.h" +#include "nsIDOMXULDocument.h" +#endif + #include "nsInlineFrame.h" #include "nsBlockFrame.h" @@ -144,6 +150,15 @@ NS_NewProgressMeterFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); nsresult NS_NewTitledButtonFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); +nsresult +NS_NewTitledBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); + +nsresult +NS_NewTitledBoxInnerFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); + +nsresult +NS_NewTitleFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); + nsresult NS_NewBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame); @@ -2036,7 +2051,7 @@ nsCSSFrameConstructor::TableIsValidCellContent(nsIPresContext* aPresContext, #ifdef INCLUDE_XUL if ( (nsXULAtoms::button == tag.get()) || (nsXULAtoms::titledbutton == tag.get()) || - (nsXULAtoms::image == tag.get()) || + (nsXULAtoms::image == tag.get()) || (nsXULAtoms::grippy == tag.get()) || (nsXULAtoms::splitter == tag.get()) || (nsXULAtoms::slider == tag.get()) || @@ -3316,6 +3331,99 @@ nsCSSFrameConstructor::InitializeSelectFrame(nsIPresShell* aPresShell, return NS_OK; } + + /** + * Used to be InitializeScrollFrame but now its only used for the select tag + * But the select tag should really be fixed to use GFX scrollbars that can + * be create with BuildScrollFrame. + */ +nsresult +nsCSSFrameConstructor::ConstructTitledBoxFrame(nsIPresShell* aPresShell, + nsIPresContext* aPresContext, + nsFrameConstructorState& aState, + nsIContent* aContent, + nsIFrame* aParentFrame, + nsIAtom* aTag, + nsIStyleContext* aStyleContext, + nsIFrame*& aNewFrame) +{ + nsIFrame * newFrame; + nsresult rv = NS_NewTitledBoxFrame(aPresShell, &newFrame); + if (!NS_SUCCEEDED(rv)) { + return rv; + } + + nsCOMPtr shell; + aPresContext->GetShell(getter_AddRefs(shell)); + + // Initialize it + nsIFrame* geometricParent = aParentFrame; + + InitAndRestoreFrame(aPresContext, aState, aContent, + geometricParent, aStyleContext, nsnull, newFrame); + + // cache our display type + const nsStyleDisplay* styleDisplay; + newFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) styleDisplay); + + nsIFrame * boxFrame; + NS_NewTitledBoxInnerFrame(shell, &boxFrame); + + + // Resolve style and initialize the frame + nsIStyleContext* styleContext; + aPresContext->ResolvePseudoStyleContextFor(aContent, nsXULAtoms::titledboxContentPseudo, + aStyleContext, PR_FALSE, &styleContext); + InitAndRestoreFrame(aPresContext, aState, nsnull, + newFrame, styleContext, nsnull, boxFrame); + + NS_RELEASE(styleContext); + + nsFrameItems childItems; + + ProcessChildren(aPresShell, aPresContext, aState, aContent, boxFrame, PR_FALSE, + childItems, PR_TRUE); + + static NS_DEFINE_IID(kTitleFrameCID, NS_TITLE_FRAME_CID); + nsIFrame * child = childItems.childList; + nsIFrame * previous = nsnull; + nsIFrame* titleFrame = nsnull; + while (nsnull != child) { + nsresult result = child->QueryInterface(kTitleFrameCID, (void**)&titleFrame); + if (NS_SUCCEEDED(result) && titleFrame) { + if (nsnull != previous) { + nsIFrame * nxt; + titleFrame->GetNextSibling(&nxt); + previous->SetNextSibling(nxt); + titleFrame->SetNextSibling(boxFrame); + break; + } else { + nsIFrame * nxt; + titleFrame->GetNextSibling(&nxt); + childItems.childList = nxt; + titleFrame->SetNextSibling(boxFrame); + break; + } + } + previous = child; + child->GetNextSibling(&child); + } + + // Set the scrolled frame's initial child lists + boxFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList); + + if (titleFrame) + newFrame->SetInitialChildList(aPresContext, nsnull, titleFrame); + else + newFrame->SetInitialChildList(aPresContext, nsnull, boxFrame); + + // our new frame retured is the top frame which is the list frame. + aNewFrame = newFrame; + + return NS_OK; +} + + /** * Used to be InitializeScrollFrame but now its only used for the select tag * But the select tag should really be fixed to use GFX scrollbars that can @@ -4292,14 +4400,65 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell, frameHasBeenInitialized = PR_TRUE; - } + } } // End of BOX CONSTRUCTION logic + else if (aTag == nsXULAtoms::title) { + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewTitleFrame(aPresShell, &newFrame); + + const nsStyleDisplay* display = (const nsStyleDisplay*) + aStyleContext->GetStyleData(eStyleStruct_Display); + + // Boxes can scroll. + if (IsScrollable(aPresContext, display)) { + + // set the top to be the newly created scrollframe + BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame, + topFrame, aStyleContext); + + // we have a scrollframe so the parent becomes the scroll frame. + newFrame->GetParent(&aParentFrame); + + primaryFrameSet = PR_TRUE; + + frameHasBeenInitialized = PR_TRUE; + + } + } // End of BOX CONSTRUCTION logic + + else if (aTag == nsXULAtoms::titledbox) { + + ConstructTitledBoxFrame(aPresShell, aPresContext, aState, aContent, aParentFrame, aTag, aStyleContext, newFrame); + processChildren = PR_FALSE; + isReplaced = PR_TRUE; + + const nsStyleDisplay* display = (const nsStyleDisplay*) + aStyleContext->GetStyleData(eStyleStruct_Display); + + // Boxes can scroll. + if (IsScrollable(aPresContext, display)) { + + // set the top to be the newly created scrollframe + BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame, + topFrame, aStyleContext); + + // we have a scrollframe so the parent becomes the scroll frame. + newFrame->GetParent(&aParentFrame); + + primaryFrameSet = PR_TRUE; + + frameHasBeenInitialized = PR_TRUE; + } + } + // TITLED BUTTON CONSTRUCTION else if (aTag == nsXULAtoms::titledbutton || aTag == nsXULAtoms::image || aTag == nsXULAtoms::text) { - processChildren = PR_TRUE; + + processChildren = PR_TRUE; isReplaced = PR_TRUE; rv = NS_NewTitledButtonFrame(aPresShell, &newFrame); } diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index d41fc11c3658..17d20c6a3b48 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -511,6 +511,15 @@ protected: PRBool& aFrameHasBeenInitialized, PRBool aIsFixedPositioned); + nsresult ConstructTitledBoxFrame(nsIPresShell* aPresShell, + nsIPresContext* aPresContext, + nsFrameConstructorState& aState, + nsIContent* aContent, + nsIFrame* aParentFrame, + nsIAtom* aTag, + nsIStyleContext* aStyleContext, + nsIFrame*& aNewFrame); + nsresult ConstructFrameByTag(nsIPresShell* aPresShell, nsIPresContext* aPresContext, nsFrameConstructorState& aState, diff --git a/layout/html/document/src/nsHTMLContentSink.cpp b/layout/html/document/src/nsHTMLContentSink.cpp index 60747d3bfa40..3b858a886291 100644 --- a/layout/html/document/src/nsHTMLContentSink.cpp +++ b/layout/html/document/src/nsHTMLContentSink.cpp @@ -3011,7 +3011,7 @@ HTMLContentSink::StartLayout() if (mWebShell) { // initially show the scrollbars. We need to do this because another // document like a XUL document, could have have hidden the scrollbars. -EDV - mWebShell->SetScrolling(-1, PR_FALSE); + //mWebShell->SetScrolling(-1, PR_FALSE); if (mFrameset) { mWebShell->SetScrolling(NS_STYLE_OVERFLOW_HIDDEN, PR_FALSE); } diff --git a/layout/html/style/src/nsCSSFrameConstructor.cpp b/layout/html/style/src/nsCSSFrameConstructor.cpp index e5f9a979983f..226b6c46fdc8 100644 --- a/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -74,9 +74,15 @@ #include "nsIAttributeContent.h" #include "nsIPref.h" #include "nsLegendFrame.h" +#include "nsTitleFrame.h" #include "nsIDOMWindow.h" #include "nsPIDOMWindow.h" +#ifdef INCLUDE_XUL +#include "nsIDOMXULCommandDispatcher.h" +#include "nsIDOMXULDocument.h" +#endif + #include "nsInlineFrame.h" #include "nsBlockFrame.h" @@ -144,6 +150,15 @@ NS_NewProgressMeterFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); nsresult NS_NewTitledButtonFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); +nsresult +NS_NewTitledBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); + +nsresult +NS_NewTitledBoxInnerFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); + +nsresult +NS_NewTitleFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame ); + nsresult NS_NewBoxFrame ( nsIPresShell* aPresShell, nsIFrame** aNewFrame); @@ -2036,7 +2051,7 @@ nsCSSFrameConstructor::TableIsValidCellContent(nsIPresContext* aPresContext, #ifdef INCLUDE_XUL if ( (nsXULAtoms::button == tag.get()) || (nsXULAtoms::titledbutton == tag.get()) || - (nsXULAtoms::image == tag.get()) || + (nsXULAtoms::image == tag.get()) || (nsXULAtoms::grippy == tag.get()) || (nsXULAtoms::splitter == tag.get()) || (nsXULAtoms::slider == tag.get()) || @@ -3316,6 +3331,99 @@ nsCSSFrameConstructor::InitializeSelectFrame(nsIPresShell* aPresShell, return NS_OK; } + + /** + * Used to be InitializeScrollFrame but now its only used for the select tag + * But the select tag should really be fixed to use GFX scrollbars that can + * be create with BuildScrollFrame. + */ +nsresult +nsCSSFrameConstructor::ConstructTitledBoxFrame(nsIPresShell* aPresShell, + nsIPresContext* aPresContext, + nsFrameConstructorState& aState, + nsIContent* aContent, + nsIFrame* aParentFrame, + nsIAtom* aTag, + nsIStyleContext* aStyleContext, + nsIFrame*& aNewFrame) +{ + nsIFrame * newFrame; + nsresult rv = NS_NewTitledBoxFrame(aPresShell, &newFrame); + if (!NS_SUCCEEDED(rv)) { + return rv; + } + + nsCOMPtr shell; + aPresContext->GetShell(getter_AddRefs(shell)); + + // Initialize it + nsIFrame* geometricParent = aParentFrame; + + InitAndRestoreFrame(aPresContext, aState, aContent, + geometricParent, aStyleContext, nsnull, newFrame); + + // cache our display type + const nsStyleDisplay* styleDisplay; + newFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) styleDisplay); + + nsIFrame * boxFrame; + NS_NewTitledBoxInnerFrame(shell, &boxFrame); + + + // Resolve style and initialize the frame + nsIStyleContext* styleContext; + aPresContext->ResolvePseudoStyleContextFor(aContent, nsXULAtoms::titledboxContentPseudo, + aStyleContext, PR_FALSE, &styleContext); + InitAndRestoreFrame(aPresContext, aState, nsnull, + newFrame, styleContext, nsnull, boxFrame); + + NS_RELEASE(styleContext); + + nsFrameItems childItems; + + ProcessChildren(aPresShell, aPresContext, aState, aContent, boxFrame, PR_FALSE, + childItems, PR_TRUE); + + static NS_DEFINE_IID(kTitleFrameCID, NS_TITLE_FRAME_CID); + nsIFrame * child = childItems.childList; + nsIFrame * previous = nsnull; + nsIFrame* titleFrame = nsnull; + while (nsnull != child) { + nsresult result = child->QueryInterface(kTitleFrameCID, (void**)&titleFrame); + if (NS_SUCCEEDED(result) && titleFrame) { + if (nsnull != previous) { + nsIFrame * nxt; + titleFrame->GetNextSibling(&nxt); + previous->SetNextSibling(nxt); + titleFrame->SetNextSibling(boxFrame); + break; + } else { + nsIFrame * nxt; + titleFrame->GetNextSibling(&nxt); + childItems.childList = nxt; + titleFrame->SetNextSibling(boxFrame); + break; + } + } + previous = child; + child->GetNextSibling(&child); + } + + // Set the scrolled frame's initial child lists + boxFrame->SetInitialChildList(aPresContext, nsnull, childItems.childList); + + if (titleFrame) + newFrame->SetInitialChildList(aPresContext, nsnull, titleFrame); + else + newFrame->SetInitialChildList(aPresContext, nsnull, boxFrame); + + // our new frame retured is the top frame which is the list frame. + aNewFrame = newFrame; + + return NS_OK; +} + + /** * Used to be InitializeScrollFrame but now its only used for the select tag * But the select tag should really be fixed to use GFX scrollbars that can @@ -4292,14 +4400,65 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresShell* aPresShell, frameHasBeenInitialized = PR_TRUE; - } + } } // End of BOX CONSTRUCTION logic + else if (aTag == nsXULAtoms::title) { + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewTitleFrame(aPresShell, &newFrame); + + const nsStyleDisplay* display = (const nsStyleDisplay*) + aStyleContext->GetStyleData(eStyleStruct_Display); + + // Boxes can scroll. + if (IsScrollable(aPresContext, display)) { + + // set the top to be the newly created scrollframe + BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame, + topFrame, aStyleContext); + + // we have a scrollframe so the parent becomes the scroll frame. + newFrame->GetParent(&aParentFrame); + + primaryFrameSet = PR_TRUE; + + frameHasBeenInitialized = PR_TRUE; + + } + } // End of BOX CONSTRUCTION logic + + else if (aTag == nsXULAtoms::titledbox) { + + ConstructTitledBoxFrame(aPresShell, aPresContext, aState, aContent, aParentFrame, aTag, aStyleContext, newFrame); + processChildren = PR_FALSE; + isReplaced = PR_TRUE; + + const nsStyleDisplay* display = (const nsStyleDisplay*) + aStyleContext->GetStyleData(eStyleStruct_Display); + + // Boxes can scroll. + if (IsScrollable(aPresContext, display)) { + + // set the top to be the newly created scrollframe + BuildScrollFrame(aPresShell, aPresContext, aState, aContent, aStyleContext, newFrame, aParentFrame, + topFrame, aStyleContext); + + // we have a scrollframe so the parent becomes the scroll frame. + newFrame->GetParent(&aParentFrame); + + primaryFrameSet = PR_TRUE; + + frameHasBeenInitialized = PR_TRUE; + } + } + // TITLED BUTTON CONSTRUCTION else if (aTag == nsXULAtoms::titledbutton || aTag == nsXULAtoms::image || aTag == nsXULAtoms::text) { - processChildren = PR_TRUE; + + processChildren = PR_TRUE; isReplaced = PR_TRUE; rv = NS_NewTitledButtonFrame(aPresShell, &newFrame); } diff --git a/layout/html/style/src/nsCSSFrameConstructor.h b/layout/html/style/src/nsCSSFrameConstructor.h index d41fc11c3658..17d20c6a3b48 100644 --- a/layout/html/style/src/nsCSSFrameConstructor.h +++ b/layout/html/style/src/nsCSSFrameConstructor.h @@ -511,6 +511,15 @@ protected: PRBool& aFrameHasBeenInitialized, PRBool aIsFixedPositioned); + nsresult ConstructTitledBoxFrame(nsIPresShell* aPresShell, + nsIPresContext* aPresContext, + nsFrameConstructorState& aState, + nsIContent* aContent, + nsIFrame* aParentFrame, + nsIAtom* aTag, + nsIStyleContext* aStyleContext, + nsIFrame*& aNewFrame); + nsresult ConstructFrameByTag(nsIPresShell* aPresShell, nsIPresContext* aPresContext, nsFrameConstructorState& aState, diff --git a/layout/xul/base/src/Makefile.in b/layout/xul/base/src/Makefile.in index a81954a38e82..09f4d714dff4 100644 --- a/layout/xul/base/src/Makefile.in +++ b/layout/xul/base/src/Makefile.in @@ -30,6 +30,8 @@ MODULE = layout LIBRARY_NAME = raptorxulbase_s CPPSRCS = \ + nsTitledBoxFrame.cpp \ + nsTitleFrame.cpp \ nsFrameNavigator.cpp \ nsSplitterFrame.cpp \ nsGrippyFrame.cpp \ diff --git a/layout/xul/base/src/makefile.win b/layout/xul/base/src/makefile.win index 2e2493771d0b..466b010ce223 100644 --- a/layout/xul/base/src/makefile.win +++ b/layout/xul/base/src/makefile.win @@ -28,6 +28,8 @@ REQUIRES=xpcom raptor pref DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN CPPSRCS= \ + nsTitleFrame.cpp \ + nsTitledBoxFrame.cpp \ nsFrameNavigator.cpp \ nsRepeatService.cpp \ nsToolbarDragListener.cpp \ @@ -66,6 +68,8 @@ CPPSRCS= \ $(NULL) CPP_OBJS= \ + .\$(OBJDIR)\nsTitleFrame.obj \ + .\$(OBJDIR)\nsTitledBoxFrame.obj \ .\$(OBJDIR)\nsFrameNavigator.obj \ .\$(OBJDIR)\nsRepeatService.obj \ .\$(OBJDIR)\nsToolbarDragListener.obj \ diff --git a/layout/xul/base/src/nsBoxFrame.cpp b/layout/xul/base/src/nsBoxFrame.cpp index 5608d6fd9ee6..b0a25da81abd 100644 --- a/layout/xul/base/src/nsBoxFrame.cpp +++ b/layout/xul/base/src/nsBoxFrame.cpp @@ -69,16 +69,22 @@ #include "nsFrameNavigator.h" #include "nsCSSRendering.h" #include "nsISelfScrollingFrame.h" +#include "nsIPref.h" #define CONSTANT 0 //#define DEBUG_REFLOW -//#define DEBUG_REDRAW +//define DEBUG_REDRAW #define DEBUG_SPRING_SIZE 8 #define DEBUG_BORDER_SIZE 2 #define COIL_SIZE 8 #define TEST_SANITY + +#define NS_STATE_IS_HORIZONTAL 0x00400000 +#define NS_STATE_AUTO_STRETCH 0x00800000 +#define NS_STATE_IS_ROOT 0x01000000 + /** * Only created when the box is in debug mode */ @@ -109,8 +115,13 @@ public: PRBool DisplayDebugInfoFor(nsIPresContext* aPresContext, nsPoint& aPoint, PRInt32& aCursor); + + + static PRBool gDebug; }; +PRBool nsBoxDebugInner::gDebug = PR_FALSE; + class nsInfoListImpl: public nsInfoList { public: @@ -170,7 +181,6 @@ public: void GetDebugInset(nsMargin& inset); void AdjustChildren(nsIPresContext* aPresContext, nsBoxFrame* aBox); - void UpdatePseudoElements(nsIPresContext* aPresContext); nsresult GetContentOf(nsIFrame* aFrame, nsIContent** aContent); void SanityCheck(); @@ -179,7 +189,9 @@ public: const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus, nsIFrame*& aIncrementalChild, - nsRect& availableSize); + nsRect& aRect, + nsSize& aActualSize, + nscoord& aMaxAscent); nsresult FlowChildAt(nsIFrame* frame, nsIPresContext* aPresContext, @@ -194,6 +206,8 @@ public: PRBool& needsRedraw, const nsString& aReason); + void UpdatePseudoElements(nsIPresContext* aPresContext); + void TranslateEventCoords(nsIPresContext* aPresContext, const nsPoint& aPoint, nsPoint& aResult); @@ -202,25 +216,8 @@ public: static void InvalidateAllCachesBelow(nsIPresContext* aPresContext, nsIFrame* aTargetFrame); static PRBool AdjustTargetToScope(nsIFrame* aParent, nsIFrame*& aTargetFrame); - enum Halignment { - hAlign_Left, - hAlign_Right, - hAlign_Center, - hAlign_Stretch, - hAlign_Default - }; - - enum Valignment { - vAlign_Top, - vAlign_Middle, - vAlign_BaseLine, - vAlign_Bottom, - vAlign_Stretch, - vAlign_Default - }; - - nsBoxFrameInner::Halignment GetHAlign(); - nsBoxFrameInner::Valignment GetVAlign(); + nsBoxFrame::Halignment GetHAlign(); + nsBoxFrame::Valignment GetVAlign(); #ifdef DEBUG_REFLOW @@ -233,13 +230,11 @@ public: nsBoxDebugInner* mDebugInner; nsInfoListImpl* mInfoList; - // make these flags! - PRBool mHorizontal; - PRBool mIsRoot; - PRBool mNeverReflowed; + // XXX make these flags! + nscoord mInnerSize; - Valignment mValign; - Halignment mHalign; + nsBoxFrame::Valignment mValign; + nsBoxFrame::Halignment mHalign; #ifdef DEBUG_REFLOW PRInt32 reflowCount; @@ -276,11 +271,11 @@ nsBoxFrame::nsBoxFrame() mInner = new nsBoxFrameInner(this); // if not otherwise specified boxes by default are horizontal. - mInner->mHorizontal = PR_TRUE; - mInner->mIsRoot = PR_FALSE; - mInner->mNeverReflowed = PR_TRUE; - mInner->mValign = nsBoxFrameInner::vAlign_Default; - mInner->mHalign = nsBoxFrameInner::hAlign_Default; + mState |= NS_STATE_IS_HORIZONTAL; + mState |= NS_STATE_AUTO_STRETCH; + mInner->mValign = nsBoxFrame::vAlign_Top; + mInner->mHalign = nsBoxFrame::hAlign_Left; + mInner->mInnerSize = 0; #ifdef DEBUG_REFLOW mInner->reflowCount = 100; @@ -302,13 +297,13 @@ nsBoxFrame::InvalidateCache(nsIFrame* aChild) // specified kids cache. if (aChild == nsnull) { while(info != nsnull) { - info->needsRecalc = PR_TRUE; + info->mFlags |= NS_FRAME_BOX_NEEDS_RECALC; info = info->next; } } else { while(info != nsnull) { if (info->frame == aChild) { - info->needsRecalc = PR_TRUE; + info->mFlags |= NS_FRAME_BOX_NEEDS_RECALC; return NS_OK; } info = info->next; @@ -339,7 +334,7 @@ nsBoxFrame::SetInitialChildList(nsIPresContext* aPresContext, PRBool nsBoxFrame::IsHorizontal() const { - return mInner->mHorizontal; + return mState & NS_STATE_IS_HORIZONTAL; } /** @@ -359,53 +354,151 @@ nsBoxFrame::Init(nsIPresContext* aPresContext, nsSpaceManager* spaceManager = new nsSpaceManager(this); mInner->mSpaceManager = spaceManager; -#ifdef DEBUG_evaughan - // This function is incredibly expensive in profiles. Unless it can be optimized, and - // because it's being used for debug purposes only, this call is being commented out. - // Contact hyatt@netscape.com if you have any questions. Do not put it back in - // until the speed issues with the pseudostyle probes have been resolved, as this - // call substantially impacts box performance. - mInner->UpdatePseudoElements(aPresContext); -#endif + mInner->mValign = nsBoxFrame::vAlign_Top; + mInner->mHalign = nsBoxFrame::hAlign_Left; - mInner->mHorizontal = GetInitialAlignment(); + GetInitialVAlignment(mInner->mValign); + GetInitialHAlignment(mInner->mHalign); + + PRBool orient = mState & NS_STATE_IS_HORIZONTAL; + GetInitialOrientation(orient); + if (orient) + mState |= NS_STATE_IS_HORIZONTAL; + else + mState &= ~NS_STATE_IS_HORIZONTAL; + + + PRBool autostretch = mState & NS_STATE_AUTO_STRETCH; + GetInitialAutoStretch(autostretch); + if (autostretch) + mState |= NS_STATE_AUTO_STRETCH; + else + mState &= ~NS_STATE_AUTO_STRETCH; + + + return rv; +} + +PRBool +nsBoxFrame::GetDefaultFlex(PRInt32& aFlex) +{ + aFlex = 0; + return PR_TRUE; +} + +PRBool +nsBoxFrame::GetInitialHAlignment(nsBoxFrame::Halignment& aHalign) +{ + nsString value; + + nsCOMPtr content; + mInner->GetContentOf(this, getter_AddRefs(content)); + + if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, value)) { + if (value.EqualsIgnoreCase("left")) { + aHalign = nsBoxFrame::hAlign_Left; + return PR_TRUE; + } else if (value.EqualsIgnoreCase("center")) { + aHalign = nsBoxFrame::hAlign_Center; + return PR_TRUE; + } else if (value.EqualsIgnoreCase("right")) { + aHalign = nsBoxFrame::hAlign_Right; + return PR_TRUE; + } + } + + // look at vertical alignment + const nsStyleText* textStyle = + (const nsStyleText*)mStyleContext->GetStyleData(eStyleStruct_Text); + + switch (textStyle->mTextAlign) + { + + case NS_STYLE_TEXT_ALIGN_RIGHT: + aHalign = nsBoxFrame::hAlign_Right; + return PR_TRUE; + break; + + case NS_STYLE_TEXT_ALIGN_CENTER: + aHalign = nsBoxFrame::hAlign_Center; + return PR_TRUE; + break; + + default: + aHalign = nsBoxFrame::hAlign_Left; + return PR_TRUE; + break; + } + + return PR_FALSE; +} + +PRBool +nsBoxFrame::GetInitialVAlignment(nsBoxFrame::Valignment& aValign) +{ nsString value; nsCOMPtr content; mInner->GetContentOf(this, getter_AddRefs(content)); - // vertical align - mInner->mValign = nsBoxFrameInner::vAlign_Default; if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::valign, value)) { - if (value.EqualsIgnoreCase("top")) - mInner->mValign = nsBoxFrameInner::vAlign_Top; - else if (value.EqualsIgnoreCase("baseline")) - mInner->mValign = nsBoxFrameInner::vAlign_BaseLine; - else if (value.EqualsIgnoreCase("middle")) - mInner->mValign = nsBoxFrameInner::vAlign_Middle; - else if (value.EqualsIgnoreCase("bottom")) - mInner->mValign = nsBoxFrameInner::vAlign_Bottom; + if (value.EqualsIgnoreCase("top")) { + aValign = nsBoxFrame::vAlign_Top; + return PR_TRUE; + } else if (value.EqualsIgnoreCase("baseline")) { + aValign = nsBoxFrame::vAlign_BaseLine; + return PR_TRUE; + } else if (value.EqualsIgnoreCase("middle")) { + aValign = nsBoxFrame::vAlign_Middle; + return PR_TRUE; + } else if (value.EqualsIgnoreCase("bottom")) { + aValign = nsBoxFrame::vAlign_Bottom; + return PR_TRUE; + } } - // horizontal align - mInner->mHalign = nsBoxFrameInner::hAlign_Default; - if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, value)) { - if (value.EqualsIgnoreCase("left")) - mInner->mHalign = nsBoxFrameInner::hAlign_Left; - else if (value.EqualsIgnoreCase("center")) - mInner->mHalign = nsBoxFrameInner::hAlign_Center; - else if (value.EqualsIgnoreCase("right")) - mInner->mHalign = nsBoxFrameInner::hAlign_Right; - } + + // look at vertical alignment + const nsStyleText* textStyle = + (const nsStyleText*)mStyleContext->GetStyleData(eStyleStruct_Text); - return rv; + if (textStyle->mVerticalAlign.GetUnit() == eStyleUnit_Enumerated) { + + PRInt32 value = textStyle->mVerticalAlign.GetIntValue(); + + switch (value) + { + case NS_STYLE_VERTICAL_ALIGN_BASELINE: + aValign = nsBoxFrame::vAlign_BaseLine; + return PR_TRUE; + break; + + case NS_STYLE_VERTICAL_ALIGN_TOP: + aValign = nsBoxFrame::vAlign_Top; + return PR_TRUE; + break; + + case NS_STYLE_VERTICAL_ALIGN_BOTTOM: + aValign = nsBoxFrame::vAlign_Bottom; + return PR_TRUE; + break; + + case NS_STYLE_VERTICAL_ALIGN_MIDDLE: + aValign = nsBoxFrame::vAlign_Middle; + return PR_TRUE; + break; + } + } + + + return PR_FALSE; } -/* Returns true if the box is horizontal and false if the box is vertical +/* Returns true if it was set. */ PRBool -nsBoxFrame::GetInitialAlignment() +nsBoxFrame::GetInitialOrientation(PRBool& aIsHorizontal) { // see if we are a vertical or horizontal box. nsString value; @@ -415,18 +508,51 @@ nsBoxFrame::GetInitialAlignment() if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsXULAtoms::orient, value)) { - if (value.EqualsIgnoreCase("vertical")) - return PR_FALSE; - else + if (value.EqualsIgnoreCase("vertical")) { + aIsHorizontal = PR_FALSE; return PR_TRUE; + } else if (value.EqualsIgnoreCase("horizontal")) { + aIsHorizontal = PR_TRUE; + return PR_TRUE; + } } else { // depricated, use align - content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, value); - if (value.EqualsIgnoreCase("vertical")) - return PR_FALSE; - else - return PR_TRUE; + if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, value)) { + if (value.EqualsIgnoreCase("vertical")) { + aIsHorizontal = PR_FALSE; + return PR_TRUE; + } else if (value.EqualsIgnoreCase("horizontal")) { + aIsHorizontal = PR_TRUE; + return PR_TRUE; + } + } } + + return PR_FALSE; +} + +/* Returns true if it was set. + */ +PRBool +nsBoxFrame::GetInitialAutoStretch(PRBool& aStretch) +{ + nsString value; + + nsCOMPtr content; + mInner->GetContentOf(this, getter_AddRefs(content)); + + if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsXULAtoms::autostretch, value)) + { + if (value.EqualsIgnoreCase("never")) { + aStretch = PR_FALSE; + return PR_TRUE; + } else if (value.EqualsIgnoreCase("always")) { + aStretch = PR_TRUE; + return PR_TRUE; + } + } + + return PR_FALSE; } nsInfoList* @@ -474,12 +600,12 @@ nsBoxFrame::GetRedefinedMinPrefMax(nsIPresContext* aPresContext, nsIFrame* aFra // see if the width or height was specifically set if (position->mWidth.GetUnit() == eStyleUnit_Coord) { aSize.prefSize.width = position->mWidth.GetCoordValue(); - aSize.prefWidthIntrinsic = PR_FALSE; + //aSize.prefWidthIntrinsic = PR_FALSE; } if (position->mHeight.GetUnit() == eStyleUnit_Coord) { aSize.prefSize.height = position->mHeight.GetCoordValue(); - aSize.prefHeightIntrinsic = PR_FALSE; + //aSize.prefHeightIntrinsic = PR_FALSE; } // same for min size. Unfortunately min size is always set to 0. So for now @@ -509,35 +635,37 @@ nsBoxFrame::GetRedefinedMinPrefMax(nsIPresContext* aPresContext, nsIFrame* aFra // get the flexibility nsCOMPtr content; - mInner->GetContentOf(aFrame, getter_AddRefs(content)); + aFrame->GetContent(getter_AddRefs(content)); - PRInt32 error; - nsAutoString value; + if (content) { + PRInt32 error; + nsAutoString value; - if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsXULAtoms::flex, value)) - { - value.Trim("%"); - aSize.flex = value.ToInteger(&error); - } + if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsXULAtoms::flex, value)) + { + value.Trim("%"); + aSize.flex = value.ToInteger(&error); + } - if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::width, value)) - { - float p2t; - aPresContext->GetScaledPixelsToTwips(&p2t); + if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::width, value)) + { + float p2t; + aPresContext->GetScaledPixelsToTwips(&p2t); - value.Trim("%"); + value.Trim("%"); - aSize.prefSize.width = NSIntPixelsToTwips(value.ToInteger(&error), p2t); - } + aSize.prefSize.width = NSIntPixelsToTwips(value.ToInteger(&error), p2t); + } - if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::height, value)) - { - float p2t; - aPresContext->GetScaledPixelsToTwips(&p2t); + if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::height, value)) + { + float p2t; + aPresContext->GetScaledPixelsToTwips(&p2t); - value.Trim("%"); + value.Trim("%"); - aSize.prefSize.height = NSIntPixelsToTwips(value.ToInteger(&error), p2t); + aSize.prefSize.height = NSIntPixelsToTwips(value.ToInteger(&error), p2t); + } } // make sure pref size is inside min and max values. @@ -648,6 +776,7 @@ nsBoxFrame::GetChildBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowStat // get the size returned and the it as the preferredsize. aSize.prefSize.width = desiredSize.width; aSize.prefSize.height = desiredSize.height; + aSize.ascent = desiredSize.ascent; // aSize.prefSize.width = 0; // aSize.prefSize.height = 0; @@ -688,7 +817,6 @@ nsIBox::HandleRootBoxReflow(nsIPresContext* aPresContext, nsIFrame* aBox, const nsHTMLReflowState& aReflowState) { - // if its an incremental reflow if ( aReflowState.reason == eReflowReason_Incremental ) { @@ -734,7 +862,6 @@ nsBoxFrame::Reflow(nsIPresContext* aPresContext, #endif - mInner->SanityCheck(); // If we have a space manager, then set it in the reflow state @@ -764,26 +891,35 @@ nsBoxFrame::Reflow(nsIPresContext* aPresContext, //--------------------------------------------------------- nsIFrame* incrementalChild = nsnull; - if (mInner->mNeverReflowed) { + if (mState & NS_FRAME_FIRST_REFLOW) { // on the initial reflow see if we are the root box. // the root box. - mInner->mIsRoot = PR_TRUE; - mInner->mNeverReflowed = PR_FALSE; + mState |= NS_STATE_IS_ROOT; // see if we are the root box nsIFrame* parent = mParent; while (parent) { nsIBox* ibox = nsnull; if (NS_SUCCEEDED(parent->QueryInterface(nsIBox::GetIID(), (void**)&ibox)) && ibox) { - mInner->mIsRoot = PR_FALSE; + mState &= ~NS_STATE_IS_ROOT; break; } parent->GetParent(&parent); } -#ifdef LAMER - if (mInner->mIsRoot) + + if (mState & NS_STATE_IS_ROOT) { + // see if someone turned on debugging + nsCOMPtr pref; + aPresContext->GetPrefs(getter_AddRefs(pref)); + nsBoxDebugInner::gDebug = PR_FALSE; + if (pref) { + pref->GetBoolPref("xul.debug.box", &nsBoxDebugInner::gDebug); + } + +#ifdef DEBUG_REFLOW printf("-------- BOX IS ROOT --------\n"); #endif + } } if ( aReflowState.reason == eReflowReason_Incremental ) { @@ -831,17 +967,36 @@ nsBoxFrame::Reflow(nsIPresContext* aPresContext, // are the first box so its our responsibility // to blow away the caches for each child in the incremental // reflow chain. only mark those children whose parents are boxes - if (mInner->mIsRoot) { + if (mState & NS_STATE_IS_ROOT) { HandleRootBoxReflow(aPresContext, this, aReflowState); - } + } } // then get the child we need to flow incrementally aReflowState.reflowCommand->GetNext(incrementalChild); } + + if (aReflowState.reason == eReflowReason_Initial ) + { + if (nsBoxDebugInner::gDebug) { + if (!mInner->mDebugInner) { + mInner->mDebugInner = new nsBoxDebugInner(this); + mInner->UpdatePseudoElements(aPresContext); + } + } else { + if (mInner->mDebugInner) + { + delete mInner->mDebugInner; + mInner->mDebugInner = nsnull; + } + } + } + + + #ifdef DEBUG_REFLOW - if (mInner->mIsRoot) + if (mState & NS_STATE_IS_ROOT) printf("--------REFLOW %d--------\n", gReflows++); #endif @@ -891,27 +1046,39 @@ printf("\n"); // now that we know our child's min, max, pref sizes. Stretch our children out to fit into our size. // this will calculate each of our childs sizes. InvalidateChildren(); - LayoutChildrenInRect(rect); + + nscoord maxAscent; + + LayoutChildrenInRect(rect, maxAscent); + //----------------------------------------------------------------------------------- //------------------------- flow all the children ----------------------------------- //----------------------------------------------------------------------------------- - // flow each child at the new sizes we have calculated. - mInner->FlowChildren(aPresContext, aDesiredSize, aReflowState, aStatus, incrementalChild, rect); + // get the layout rect. + nsRect layoutRect = rect; + + // set up our actual size + layoutRect.Inflate(inset); + + if (aReflowState.mComputedWidth != NS_INTRINSICSIZE && layoutRect.width < aReflowState.mComputedWidth) + layoutRect.width = aReflowState.mComputedWidth; + + if (aReflowState.mComputedHeight != NS_INTRINSICSIZE && layoutRect.height < aReflowState.mComputedHeight) + layoutRect.height = aReflowState.mComputedHeight; + + nsSize actualSize(layoutRect.width, layoutRect.height); + + // flow each child at the new sizes we have calculated. + mInner->FlowChildren(aPresContext, aDesiredSize, aReflowState, aStatus, incrementalChild, rect, actualSize, maxAscent); + - /* - //----------------------------------------------------------------------------------- - //------------------------- Adjust each childs x, y location------------------------- - //----------------------------------------------------------------------------------- - // set the x,y locations of each of our children. Taking into acount their margins, our border, - // and insets. - PlaceChildren(aPresContext,rect); -*/ //----------------------------------------------------------------------------------- //------------------------- Add our border and insets in ---------------------------- //----------------------------------------------------------------------------------- + rect.Inflate(inset); if (aReflowState.mComputedWidth != NS_INTRINSICSIZE && rect.width < aReflowState.mComputedWidth) @@ -919,7 +1086,8 @@ printf("\n"); if (aReflowState.mComputedHeight != NS_INTRINSICSIZE && rect.height < aReflowState.mComputedHeight) rect.height = aReflowState.mComputedHeight; - + + rect.Inflate(aReflowState.mComputedBorderPadding); // the rect might have gotten bigger so recalc ourSize @@ -990,40 +1158,48 @@ nsBoxFrameInner::InvalidateAllCachesBelow(nsIPresContext* aPresContext, nsIFrame } void -nsBoxFrame::ComputeChildsNextPosition( nsIFrame* aChild, nscoord& aCurX, nscoord& aCurY, nscoord& aNextX, nscoord& aNextY, const nsSize& aCurrentChildSize, const nsRect& aBoxRect) +nsBoxFrame::ComputeChildsNextPosition(nsCalculatedBoxInfo* aInfo, nscoord& aCurX, nscoord& aCurY, nscoord& aNextX, nscoord& aNextY, const nsSize& aCurrentChildSize, const nsRect& aBoxRect, nscoord aMaxAscent) { - if (mInner->mHorizontal) { + if (mState & NS_STATE_IS_HORIZONTAL) { aNextX = aCurX + aCurrentChildSize.width; - switch (mInner->mValign) - { - case nsBoxFrameInner::vAlign_Top: - case nsBoxFrameInner::vAlign_BaseLine: - case nsBoxFrameInner::vAlign_Stretch: - case nsBoxFrameInner::vAlign_Default: + + if (mState & NS_STATE_AUTO_STRETCH) { aCurY = aBoxRect.y; + } else { + switch (mInner->mValign) + { + case nsBoxFrame::vAlign_BaseLine: + aCurY = aBoxRect.y + (aMaxAscent - aInfo->ascent); break; - case nsBoxFrameInner::vAlign_Middle: - aCurY = aBoxRect.y + (aBoxRect.height/2 - aCurrentChildSize.height/2); - break; - case nsBoxFrameInner::vAlign_Bottom: - aCurY = aBoxRect.y + aBoxRect.height - aCurrentChildSize.height; - break; + + case nsBoxFrame::vAlign_Top: + aCurY = aBoxRect.y; + break; + case nsBoxFrame::vAlign_Middle: + aCurY = aBoxRect.y + (aBoxRect.height/2 - aCurrentChildSize.height/2); + break; + case nsBoxFrame::vAlign_Bottom: + aCurY = aBoxRect.y + aBoxRect.height - aCurrentChildSize.height; + break; + } } } else { aNextY = aCurY + aCurrentChildSize.height; - switch (mInner->mHalign) - { - case nsBoxFrameInner::hAlign_Left: - case nsBoxFrameInner::hAlign_Stretch: - case nsBoxFrameInner::hAlign_Default: - aCurX = aBoxRect.x; - break; - case nsBoxFrameInner::hAlign_Center: - aCurX = aBoxRect.x + (aBoxRect.width/2 - aCurrentChildSize.width/2); - break; - case nsBoxFrameInner::hAlign_Right: - aCurX = aBoxRect.x + aBoxRect.width - aCurrentChildSize.width; - break; + if (mState & NS_STATE_AUTO_STRETCH) { + aCurX = aBoxRect.x; + } else { + switch (mInner->mHalign) + { + case nsBoxFrame::hAlign_Left: + aCurX = aBoxRect.x; + break; + case nsBoxFrame::hAlign_Center: + aCurX = aBoxRect.x + (aBoxRect.width/2 - aCurrentChildSize.width/2); + break; + case nsBoxFrame::hAlign_Right: + aCurX = aBoxRect.x + aBoxRect.width - aCurrentChildSize.width; + break; + } } } } @@ -1038,7 +1214,9 @@ nsBoxFrameInner::FlowChildren(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus, nsIFrame*& aIncrementalChild, - nsRect& aRect) + nsRect& aRect, + nsSize& aActualSize, + nscoord& aMaxAscent) { // ------- set the childs positions --------- @@ -1084,6 +1262,39 @@ nsBoxFrameInner::FlowChildren(nsIPresContext* aPresContext, nscoord x = aRect.x; nscoord y = aRect.y; + if (!(mOuter->mState & NS_STATE_AUTO_STRETCH)) { + if (mOuter->mState & NS_STATE_IS_HORIZONTAL) { + switch(mHalign) { + case nsBoxFrame::hAlign_Left: + x = aRect.x; + break; + + case nsBoxFrame::hAlign_Center: + x = aRect.x + (aActualSize.width - aRect.width)/2; + break; + + case nsBoxFrame::hAlign_Right: + x = aRect.x + (aActualSize.width - aRect.width); + break; + } + } else { + switch(mValign) { + case nsBoxFrame::vAlign_Top: + case nsBoxFrame::vAlign_BaseLine: + y = aRect.y; + break; + + case nsBoxFrame::vAlign_Middle: + y = aRect.y + (aActualSize.height - aRect.height)/2; + break; + + case nsBoxFrame::vAlign_Bottom: + y = aRect.y + (aActualSize.height - aRect.height); + break; + } + } + } + while (nsnull != info) { @@ -1096,14 +1307,14 @@ nsBoxFrameInner::FlowChildren(nsIPresContext* aPresContext, // break; // make collapsed children not show up - if (info->collapsed) { + if (info->mFlags & NS_FRAME_BOX_IS_COLLAPSED) { if (aReflowState.reason == eReflowReason_Initial) { FlowChildAt(childFrame, aPresContext, aDesiredSize, aReflowState, aStatus, *info, x, y, PR_TRUE, aIncrementalChild, redraw, reason); // if the child got bigger then adjust our rect and all the children. - mOuter->ChildResized(childFrame, aDesiredSize, aRect, *info, resized, changedIndex, finished, count, nextReason); + mOuter->ChildResized(childFrame, aDesiredSize, aRect, aMaxAscent, *info, resized, changedIndex, finished, count, nextReason); } // ok if we are collapsed make sure the view and all its children @@ -1138,13 +1349,13 @@ nsBoxFrameInner::FlowChildren(nsIPresContext* aPresContext, nscoord nextX = x; nscoord nextY = y; - mOuter->ComputeChildsNextPosition(childFrame, x, y, nextX, nextY, info->calculatedSize, aRect); + mOuter->ComputeChildsNextPosition(info, x, y, nextX, nextY, info->calculatedSize, aRect, aMaxAscent); // reflow if the child needs it or we are on a second pass FlowChildAt(childFrame, aPresContext, aDesiredSize, aReflowState, aStatus, *info, x, y, PR_TRUE, aIncrementalChild, redraw, reason); // if the child got bigger then adjust our rect and all the children. - mOuter->ChildResized(childFrame, aDesiredSize, aRect, *info, resized, changedIndex, finished, count, nextReason); + mOuter->ChildResized(childFrame, aDesiredSize, aRect, aMaxAscent, *info, resized, changedIndex, finished, count, nextReason); /* #ifdef DEBUG_REFLOW @@ -1167,7 +1378,7 @@ nsBoxFrameInner::FlowChildren(nsIPresContext* aPresContext, // if the child resized then recompute it position. if (!finished) { - mOuter->ComputeChildsNextPosition(childFrame, x, y, nextX, nextY, nsSize(aDesiredSize.width, aDesiredSize.height), aRect); + mOuter->ComputeChildsNextPosition(info, x, y, nextX, nextY, nsSize(aDesiredSize.width, aDesiredSize.height), aRect, aMaxAscent); } x = nextX; @@ -1198,7 +1409,22 @@ nsBoxFrameInner::FlowChildren(nsIPresContext* aPresContext, } while (PR_FALSE == finished); - // redraw things if needed. + + // if the rect inside us changes size. Mainly if it gets smaller redraw. + // this will make use draw when children have removed. + nscoord newInnerSize; + if (mOuter->mState & NS_STATE_IS_HORIZONTAL) + newInnerSize = aRect.width; + else + newInnerSize = aRect.height; + + if (mInnerSize != newInnerSize) + { + mInnerSize = newInnerSize; + redraw = PR_TRUE; + } + + // redraw things if needed. if (redraw) { #ifdef DEBUG_REDRAW mInner->ListTag(stdout); @@ -1247,9 +1473,9 @@ nsBoxFrameInner::MakeReason(nsIFrame* aFrame, const nsString& aText, nsString& a #endif void -nsBoxFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nsCalculatedBoxInfo& aInfo, PRBool* aResized, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason) +nsBoxFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nscoord& aMaxAscent, nsCalculatedBoxInfo& aInfo, PRBool* aResized, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason) { - if (mInner->mHorizontal) { + if (mState & NS_STATE_IS_HORIZONTAL) { // if we are a horizontal box see if the child will fit inside us. if ( aDesiredSize.height > aRect.height) { // if we are a horizontal box and the the child it bigger than our height @@ -1267,7 +1493,7 @@ nsBoxFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, ns // relayout everything InvalidateChildren(); - LayoutChildrenInRect(aRect); + LayoutChildrenInRect(aRect, aMaxAscent); #ifdef DEBUG_REFLOW mInner->MakeReason(aFrame, "height got bigger", aReason); #endif @@ -1311,12 +1537,17 @@ nsBoxFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, ns nsCalculatedBoxInfo* info = mInner->mInfoList->GetFirst(); PRInt32 infoCount = 0; while(info) { - info->sizeValid = aResized[infoCount]; + if (aResized[infoCount]) + info->mFlags |= NS_FRAME_BOX_SIZE_VALID; + else + info->mFlags &= ~NS_FRAME_BOX_SIZE_VALID; + + info = info->next; infoCount++; } - LayoutChildrenInRect(aRect); + LayoutChildrenInRect(aRect, aMaxAscent); aFinished = PR_FALSE; aChangedIndex = aIndex; #ifdef DEBUG_REFLOW @@ -1360,7 +1591,7 @@ nsBoxFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, ns // relayout everything InvalidateChildren(); - LayoutChildrenInRect(aRect); + LayoutChildrenInRect(aRect, aMaxAscent); #ifdef DEBUG_REFLOW mInner->MakeReason(aFrame, "width got bigger", aReason); #endif @@ -1378,12 +1609,16 @@ nsBoxFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, ns nsCalculatedBoxInfo* info = mInner->mInfoList->GetFirst(); PRInt32 infoCount = 0; while(info) { - info->sizeValid = aResized[infoCount]; + if (aResized[infoCount]) + info->mFlags |= NS_FRAME_BOX_SIZE_VALID; + else + info->mFlags &= ~NS_FRAME_BOX_SIZE_VALID; + info = info->next; infoCount++; } - LayoutChildrenInRect(aRect); + LayoutChildrenInRect(aRect, aMaxAscent); aFinished = PR_FALSE; aChangedIndex = aIndex; #ifdef DEBUG_REFLOW @@ -1487,7 +1722,7 @@ nsBoxFrame::PlaceChildren(nsIPresContext* aPresContext, nsRect& boxRect) nsresult rv; // make collapsed children not show up - if (info->collapsed) { + if (info->mFlags & NS_FRAME_BOX_IS_COLLAPSED) { nsRect rect(0,0,0,0); childFrame->GetRect(rect); if (rect.width > 0 || rect.height > 0) { @@ -1502,7 +1737,7 @@ nsBoxFrame::PlaceChildren(nsIPresContext* aPresContext, nsRect& boxRect) nsMargin margin(0,0,0,0); spacing->GetMargin(margin); - if (mInner->mHorizontal) { + if (mState & NS_STATE_IS_HORIZONTAL) { x += margin.left; y = boxRect.y + margin.top; } else { @@ -1530,12 +1765,12 @@ nsBoxFrame::PlaceChildren(nsIPresContext* aPresContext, nsRect& boxRect) } // add in the right margin - if (mInner->mHorizontal) + if (mState & NS_STATE_IS_HORIZONTAL) x += margin.right; else y += margin.bottom; - if (mInner->mHorizontal) { + if (mState & NS_STATE_IS_HORIZONTAL) { x += rect.width; //width += rect.width + margin.left + margin.right; } else { @@ -1576,7 +1811,10 @@ nsBoxFrameInner::FlowChildAt(nsIFrame* childFrame, PRBool needsReflow = PR_FALSE; nsReflowReason reason = aReflowState.reason; - if (aInfo.neverReflowed) { + nsFrameState childState; + aInfo.frame->GetFrameState(&childState); + + if (childState & NS_FRAME_FIRST_REFLOW) { NS_ASSERTION(reason != eReflowReason_Incremental,"Error should not be incremental!!"); reason = eReflowReason_Initial; } else if (reason == eReflowReason_Initial) { @@ -1608,9 +1846,7 @@ nsBoxFrameInner::FlowChildAt(nsIFrame* childFrame, // mark it as needing to be reflowed. case eReflowReason_Dirty: // get the frame state to see if it needs reflow - nsFrameState state; - aInfo.frame->GetFrameState(&state); - needsReflow = (state & NS_FRAME_IS_DIRTY) || (state & NS_FRAME_HAS_DIRTY_CHILDREN); + needsReflow = (childState & NS_FRAME_IS_DIRTY) || (childState & NS_FRAME_HAS_DIRTY_CHILDREN); break; // if the a resize reflow then it doesn't need to be reflowed. Only if the size is different @@ -1619,6 +1855,13 @@ nsBoxFrameInner::FlowChildAt(nsIFrame* childFrame, needsReflow = PR_FALSE; break; + // if its an initial reflow we must place the child. + // otherwise we might think it was already placed when it wasn't + case eReflowReason_Initial: + aMoveFrame = PR_TRUE; + needsReflow = PR_TRUE; + break; + default: needsReflow = PR_TRUE; @@ -1786,7 +2029,6 @@ nsBoxFrameInner::FlowChildAt(nsIFrame* childFrame, } childFrame->Reflow(aPresContext, desiredSize, reflowState, aStatus); - aInfo.neverReflowed = PR_FALSE; NS_ASSERTION(NS_FRAME_IS_COMPLETE(aStatus), "bad status"); @@ -1857,7 +2099,7 @@ nsBoxFrameInner::FlowChildAt(nsIFrame* childFrame, // Stub out desiredSize.maxElementSize so that when go out of // scope, nothing bad happens! - desiredSize.maxElementSize = nsnull; + //desiredSize.maxElementSize = nsnull; } else { if (aMoveFrame) { @@ -1865,7 +2107,7 @@ nsBoxFrameInner::FlowChildAt(nsIFrame* childFrame, childFrame->GetOrigin(curOrigin); // only if the origin changed - if ((curOrigin.x != aX) || (curOrigin.y != aY)) { + //if ((curOrigin.x != aX + margin.left) || (curOrigin.y != aY + margin.top)) { childFrame->MoveTo(aPresContext, aX + margin.left, aY + margin.top); @@ -1875,7 +2117,7 @@ nsBoxFrameInner::FlowChildAt(nsIFrame* childFrame, nsContainerFrame::PositionFrameView(aPresContext, childFrame, view); else nsContainerFrame::PositionChildViews(aPresContext, childFrame); - } + // } } } @@ -1902,7 +2144,13 @@ nsBoxFrameInner::FlowChildAt(nsIFrame* childFrame, } #endif - + + if (aInfo.calculatedSize.width == NS_INTRINSICSIZE) + aInfo.calculatedSize.width = desiredSize.width; + + if (aInfo.calculatedSize.height == NS_INTRINSICSIZE) + aInfo.calculatedSize.height = desiredSize.height; + return NS_OK; } @@ -1950,10 +2198,10 @@ nsBoxFrame::AddSize(const nsSize& a, nsSize& b, PRBool largest) { // depending on the dimension switch either the width or the height component. - const nscoord& awidth = mInner->mHorizontal ? a.width : a.height; - const nscoord& aheight = mInner->mHorizontal ? a.height : a.width; - nscoord& bwidth = mInner->mHorizontal ? b.width : b.height; - nscoord& bheight = mInner->mHorizontal ? b.height : b.width; + const nscoord& awidth = (mState & NS_STATE_IS_HORIZONTAL) ? a.width : a.height; + const nscoord& aheight = (mState & NS_STATE_IS_HORIZONTAL) ? a.height : a.width; + nscoord& bwidth = (mState & NS_STATE_IS_HORIZONTAL) ? b.width : b.height; + nscoord& bheight = (mState & NS_STATE_IS_HORIZONTAL) ? b.height : b.width; // add up the widths make sure we check for intrinsic. if (bwidth != NS_INTRINSICSIZE) // if we are already intrinsic we are done @@ -1982,50 +2230,18 @@ nsBoxFrame::InvalidateChildren() { nsCalculatedBoxInfo* info = mInner->mInfoList->GetFirst(); while(info) { - info->sizeValid = PR_FALSE; + info->mFlags &= ~NS_FRAME_BOX_SIZE_VALID; info = info->next; } } -nsBoxFrameInner::Valignment +nsBoxFrame::Valignment nsBoxFrameInner::GetVAlign() { - /* - if (mValign == nsBoxFrameInner::vAlign_Default) { - // look at vertical alignment - const nsStyleText* textStyle = - (const nsStyleText*)mOuter->mStyleContext->GetStyleData(eStyleStruct_Text); - - if (textStyle->mVerticalAlign.GetUnit() == eStyleUnit_Enumerated) { - - PRInt32 value = textStyle->mVerticalAlign.GetIntValue(); - - switch (value) - { - case NS_STYLE_VERTICAL_ALIGN_BASELINE: - return nsBoxFrameInner::vAlign_BaseLine; - break; - - case NS_STYLE_VERTICAL_ALIGN_TOP: - return nsBoxFrameInner::vAlign_Top; - break; - - case NS_STYLE_VERTICAL_ALIGN_BOTTOM: - return nsBoxFrameInner::vAlign_Bottom; - break; - - case NS_STYLE_VERTICAL_ALIGN_MIDDLE: - return nsBoxFrameInner::vAlign_Middle; - break; - } - } - } -*/ - return mValign; } -nsBoxFrameInner::Halignment +nsBoxFrame::Halignment nsBoxFrameInner::GetHAlign() { return mHalign; @@ -2033,10 +2249,10 @@ nsBoxFrameInner::GetHAlign() void -nsBoxFrame::LayoutChildrenInRect(nsRect& size) +nsBoxFrame::LayoutChildrenInRect(nsRect& aGivenSize, nscoord& aMaxAscent) { - nsBoxFrameInner::Valignment valign = mInner->GetVAlign(); - nsBoxFrameInner::Halignment halign = mInner->GetHAlign(); + nsBoxFrame::Valignment valign = mInner->GetVAlign(); + nsBoxFrame::Halignment halign = mInner->GetHAlign(); nsCalculatedBoxInfo* first = mInner->mInfoList->GetFirst(); @@ -2045,10 +2261,10 @@ nsBoxFrame::LayoutChildrenInRect(nsRect& size) PRInt32 sizeRemaining; - if (mInner->mHorizontal) - sizeRemaining = size.width; + if (mState & NS_STATE_IS_HORIZONTAL) + sizeRemaining = aGivenSize.width; else - sizeRemaining = size.height; + sizeRemaining = aGivenSize.height; PRInt32 springConstantsRemaining = 0; @@ -2056,7 +2272,7 @@ nsBoxFrame::LayoutChildrenInRect(nsRect& size) while(info) { // ignore collapsed children - if (info->collapsed) { + if (info->mFlags & NS_FRAME_BOX_IS_COLLAPSED) { info = info->next; continue; } @@ -2065,15 +2281,11 @@ nsBoxFrame::LayoutChildrenInRect(nsRect& size) nscoord pref = GET_WIDTH(info->prefSize); nscoord min = GET_WIDTH(info->minSize); - - PRBool hstretch = (halign == nsBoxFrameInner::hAlign_Stretch || halign == nsBoxFrameInner::hAlign_Default); - PRBool vstretch = (valign == nsBoxFrameInner::vAlign_Stretch || valign == nsBoxFrameInner::vAlign_Default); - - - if ((mInner->mHorizontal && vstretch) || (!mInner->mHorizontal && hstretch)) + + if (mState & NS_STATE_AUTO_STRETCH) { // stretch - nscoord h = GET_HEIGHT(size); + nscoord h = GET_HEIGHT(aGivenSize); nscoord max1 = GET_HEIGHT(info->maxSize); nscoord min1 = GET_HEIGHT(info->minSize); if (h < min1) @@ -2085,7 +2297,7 @@ nsBoxFrame::LayoutChildrenInRect(nsRect& size) } else { // go to preferred size nscoord h = GET_HEIGHT(info->prefSize); - nscoord s = GET_HEIGHT(size); + nscoord s = GET_HEIGHT(aGivenSize); if (h > s) h = s; @@ -2099,57 +2311,17 @@ nsBoxFrame::LayoutChildrenInRect(nsRect& size) SET_HEIGHT(info->calculatedSize, h); } - /* - switch (mInner->mValign) - { - case nsBoxFrameInner::Top: - case nsBoxFrameInner::Bottom: - case nsBoxFrameInner::Right: - { - nscoord h = GET_HEIGHT(info->prefSize); - nscoord s = GET_HEIGHT(size); - if (h > s) - h = s; - - nscoord max = GET_HEIGHT(info->maxSize); - nscoord min = GET_HEIGHT(info->minSize); - if (h < min) - h = min; - else if (h > max) - h = max; - - SET_HEIGHT(info->calculatedSize, h); - } - break; - - case nsBoxFrameInner::Stretch: - { - nscoord h = GET_HEIGHT(size); - nscoord max = GET_HEIGHT(info->maxSize); - nscoord min = GET_HEIGHT(info->minSize); - if (h < min) - h = min; - else if (h > max) - h = max; - - SET_HEIGHT(info->calculatedSize, h); - } - break; - } - } - */ - if (pref < min) { pref = min; SET_WIDTH(info->prefSize, min); } - if (info->sizeValid) { + if (info->mFlags & NS_FRAME_BOX_SIZE_VALID) { sizeRemaining -= GET_WIDTH(info->calculatedSize); } else { if (info->flex == 0) { - info->sizeValid = PR_TRUE; + info->mFlags |= NS_FRAME_BOX_SIZE_VALID; SET_WIDTH(info->calculatedSize, pref); } sizeRemaining -= pref; @@ -2159,25 +2331,25 @@ nsBoxFrame::LayoutChildrenInRect(nsRect& size) info = info->next; } - nscoord& sz = GET_WIDTH(size); + nscoord& sz = GET_WIDTH(aGivenSize); if (sz == NS_INTRINSICSIZE) { sz = 0; info = first; while(info) { // ignore collapsed springs - if (info->collapsed) { + if (info->mFlags & NS_FRAME_BOX_IS_COLLAPSED) { info = info->next; continue; } nscoord pref = GET_WIDTH(info->prefSize); - if (!info->sizeValid) + if (!(info->mFlags & NS_FRAME_BOX_SIZE_VALID)) { // set the calculated size to be the preferred size SET_WIDTH(info->calculatedSize, pref); - info->sizeValid = PR_TRUE; + info->mFlags |= NS_FRAME_BOX_SIZE_VALID; } // changed the size returned to reflect @@ -2195,7 +2367,7 @@ nsBoxFrame::LayoutChildrenInRect(nsRect& size) info = first; while(info) { // ignore collapsed springs - if (info->collapsed) { + if (info->mFlags & NS_FRAME_BOX_IS_COLLAPSED) { info = info->next; continue; } @@ -2205,7 +2377,7 @@ nsBoxFrame::LayoutChildrenInRect(nsRect& size) nscoord min = GET_WIDTH(info->minSize); nscoord calculated = GET_WIDTH(info->calculatedSize); - if (info->sizeValid==PR_FALSE) { + if (!(info->mFlags & NS_FRAME_BOX_SIZE_VALID)) { PRInt32 newSize = pref + (sizeRemaining*info->flex/springConstantsRemaining); if (newSize<=min) { SET_WIDTH(info->calculatedSize, min); @@ -2213,7 +2385,7 @@ nsBoxFrame::LayoutChildrenInRect(nsRect& size) sizeRemaining += pref; sizeRemaining -= min; - info->sizeValid = PR_TRUE; + info->mFlags |= NS_FRAME_BOX_SIZE_VALID; limit = PR_TRUE; } else if (newSize>=max) { @@ -2221,7 +2393,7 @@ nsBoxFrame::LayoutChildrenInRect(nsRect& size) springConstantsRemaining -= info->flex; sizeRemaining += pref; sizeRemaining -= max; - info->sizeValid = PR_TRUE; + info->mFlags |= NS_FRAME_BOX_SIZE_VALID; limit = PR_TRUE; } } @@ -2229,20 +2401,22 @@ nsBoxFrame::LayoutChildrenInRect(nsRect& size) } } - nscoord& s = GET_WIDTH(size); - s = 0; + nscoord& s = GET_WIDTH(aGivenSize); + s = 0; + aMaxAscent = 0; + info = first; while(info) { // ignore collapsed springs - if (info->collapsed) { + if (info->mFlags & NS_FRAME_BOX_IS_COLLAPSED) { info = info->next; continue; } nscoord pref = GET_WIDTH(info->prefSize); - if (info->sizeValid==PR_FALSE) { + if (!(info->mFlags & NS_FRAME_BOX_SIZE_VALID)) { if (springConstantsRemaining == 0) { SET_WIDTH(info->calculatedSize, pref); } @@ -2250,10 +2424,14 @@ nsBoxFrame::LayoutChildrenInRect(nsRect& size) SET_WIDTH(info->calculatedSize, pref + info->flex*sizeRemaining/springConstantsRemaining); } - info->sizeValid = PR_TRUE; + info->mFlags |= NS_FRAME_BOX_SIZE_VALID; } s += GET_WIDTH(info->calculatedSize); + + if (info->ascent > aMaxAscent) + aMaxAscent = info->ascent; + info = info->next; } } @@ -2394,6 +2572,7 @@ nsBoxFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aR nsresult rv; aSize.Clear(); + GetDefaultFlex(aSize.flex); // run through all the children and get there min, max, and preferred sizes // return us the size of the box @@ -2404,7 +2583,7 @@ nsBoxFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aR { // if a child needs recalculation then ask it for its size. Otherwise // just use the size we already have. - if (info->needsRecalc) + if (info->mFlags & NS_FRAME_BOX_NEEDS_RECALC) { // see if the child is collapsed const nsStyleDisplay* disp; @@ -2414,7 +2593,7 @@ nsBoxFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aR // don't unset needsRecalc - therefore cause us // to be recalculated when we are uncollapsed if (disp->mVisible == NS_STYLE_VISIBILITY_COLLAPSE) - info->collapsed = PR_TRUE; + info->mFlags |= NS_FRAME_BOX_IS_COLLAPSED; else { // get the size of the child. This is the min, max, preferred, and spring constant // it does not include its border. @@ -2462,12 +2641,25 @@ nsBoxFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aR info->maxSize.height += b.height; // ok we don't need to calc this guy again - info->needsRecalc = PR_FALSE; + info->mFlags &= ~NS_FRAME_BOX_NEEDS_RECALC; } } AddChildSize(aSize, *info); + // if horizontal get the largest child's ascent + if (mState & NS_STATE_IS_HORIZONTAL) { + if (info->ascent > aSize.ascent) + aSize.ascent = info->ascent; + } else { + // if vertical then get the last child's ascent. + if (info->next) + aSize.ascent += info->prefSize.height; + else + aSize.ascent += info->ascent; + + } + info = info->next; } @@ -2489,6 +2681,9 @@ nsBoxFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aR if (aSize.maxSize.height < debugInset.top + debugInset.bottom) aSize.maxSize.height = debugInset.top + debugInset.bottom; + aSize.ascent += inset.top; + aSize.ascent += debugInset.top; + return rv; } @@ -2590,11 +2785,14 @@ nsBoxDebugInner::PaintSprings(nsIPresContext* aPresContext, nsIRenderingContext& nscoord onePixel = NSIntPixelsToTwips(1, p2t); nsIStyleContext* debugStyle; - if (mOuter->mInner->mHorizontal) + if (mOuter->mState & NS_STATE_IS_HORIZONTAL) debugStyle = mHorizontalDebugStyle; else debugStyle = mVerticalDebugStyle; + if (debugStyle == nsnull) + return; + const nsStyleSpacing* debugSpacing = (const nsStyleSpacing*)debugStyle->GetStyleData(eStyleStruct_Spacing); const nsStyleColor* debugColor = @@ -2624,7 +2822,7 @@ nsBoxDebugInner::PaintSprings(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext.SetColor(debugColor->mColor); - if (mOuter->mInner->mHorizontal) + if (mOuter->mState & NS_STATE_IS_HORIZONTAL) { x = inner.x; y = inner.y + onePixel; @@ -2640,8 +2838,8 @@ nsBoxDebugInner::PaintSprings(nsIPresContext* aPresContext, nsIRenderingContext& nsCalculatedBoxInfo* info = mOuter->GetInfoList()->GetFirst(); while (info) { nsSize& size = info->calculatedSize; - if (!info->collapsed) { - if (mOuter->mInner->mHorizontal) + if (!(info->mFlags & NS_FRAME_BOX_IS_COLLAPSED)) { + if (mOuter->mState & NS_STATE_IS_HORIZONTAL) borderSize = size.width; else borderSize = size.height; @@ -2668,7 +2866,7 @@ nsBoxDebugInner::PaintSprings(nsIPresContext* aPresContext, nsIRenderingContext& void nsBoxDebugInner::DrawLine(nsIRenderingContext& aRenderingContext, nscoord x1, nscoord y1, nscoord x2, nscoord y2) { - if (mOuter->mInner->mHorizontal) + if (mOuter->mState & NS_STATE_IS_HORIZONTAL) aRenderingContext.DrawLine(x1,y1,x2,y2); else aRenderingContext.DrawLine(y1,x1,y2,x2); @@ -2677,7 +2875,7 @@ nsBoxDebugInner::DrawLine(nsIRenderingContext& aRenderingContext, nscoord x1, ns void nsBoxDebugInner::FillRect(nsIRenderingContext& aRenderingContext, nscoord x, nscoord y, nscoord width, nscoord height) { - if (mOuter->mInner->mHorizontal) + if (mOuter->mState & NS_STATE_IS_HORIZONTAL) aRenderingContext.FillRect(x,y,width,height); else aRenderingContext.FillRect(y,x,height,width); @@ -2685,9 +2883,7 @@ nsBoxDebugInner::FillRect(nsIRenderingContext& aRenderingContext, nscoord x, nsc void nsBoxDebugInner::DrawSpring(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, PRInt32 flex, nscoord x, nscoord y, nscoord size, nscoord springSize) -{ - // PRBool h = mOuter->mHorizontal; - +{ float p2t; aPresContext->GetScaledPixelsToTwips(&p2t); nscoord onePixel = NSIntPixelsToTwips(1, p2t); @@ -2744,20 +2940,10 @@ nsBoxFrameInner::UpdatePseudoElements(nsIPresContext* aPresContext) PR_FALSE, getter_AddRefs(vs)); - if (hs && vs) { - if (!mDebugInner) { - mDebugInner = new nsBoxDebugInner(mOuter); - } - mDebugInner->mHorizontalDebugStyle = hs; - mDebugInner->mVerticalDebugStyle = vs; - aPresContext->GetScaledPixelsToTwips(&mDebugInner->mP2t); - } else { - if (mDebugInner) - { - delete mDebugInner; - mDebugInner = nsnull; - } - } + mDebugInner->mHorizontalDebugStyle = hs; + mDebugInner->mVerticalDebugStyle = vs; + aPresContext->GetScaledPixelsToTwips(&mDebugInner->mP2t); + } @@ -2769,11 +2955,14 @@ nsBoxFrameInner::GetDebugInset(nsMargin& inset) if (mDebugInner) { nsIStyleContext* style; - if (mOuter->mInner->mHorizontal) + if (mOuter->mState & NS_STATE_IS_HORIZONTAL) style = mDebugInner->mHorizontalDebugStyle; else style = mDebugInner->mVerticalDebugStyle; + if (style == nsnull) + return; + const nsStyleSpacing* debugSpacing = (const nsStyleSpacing*)style->GetStyleData(eStyleStruct_Spacing); @@ -2808,9 +2997,12 @@ NS_INTERFACE_MAP_END_INHERITING(nsHTMLContainerFrame) NS_IMETHODIMP nsBoxFrame::GetFrameName(nsString& aResult) const { + nsCOMPtr content; + nsIFrame* frame = (nsIFrame*)this; + mInner->GetContentOf(frame, getter_AddRefs(content)); nsString id; - mContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id); + content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id); aResult = "Box[id="; aResult.Append(id); @@ -2825,16 +3017,19 @@ nsCalculatedBoxInfoImpl::nsCalculatedBoxInfoImpl(nsIFrame* aFrame) //gBoxInfoCount++; // printf("created Info=%d\n",gBoxInfoCount); + mFlags = NS_FRAME_BOX_NEEDS_RECALC; next = nsnull; - collapsed = PR_FALSE; calculatedSize.width = 0; calculatedSize.height = 0; - sizeValid = PR_FALSE; frame = aFrame; - prefWidthIntrinsic = PR_TRUE; - prefHeightIntrinsic = PR_TRUE; - needsRecalc = PR_TRUE; - neverReflowed = PR_TRUE; + prefSize.width = 0; + prefSize.height = 0; + minSize.width = 0; + minSize.height = 0; + ascent = 0; + flex = 0; + maxSize.width = NS_INTRINSICSIZE; + maxSize.height = NS_INTRINSICSIZE; } nsCalculatedBoxInfoImpl::~nsCalculatedBoxInfoImpl() @@ -2848,16 +3043,13 @@ nsCalculatedBoxInfoImpl::Clear() { nsBoxInfo::Clear(); - collapsed = PR_FALSE; - needsRecalc = PR_TRUE; + mFlags = NS_FRAME_BOX_NEEDS_RECALC; calculatedSize.width = 0; calculatedSize.height = 0; - sizeValid = PR_FALSE; - - prefWidthIntrinsic = PR_TRUE; - prefHeightIntrinsic = PR_TRUE; + //prefWidthIntrinsic = PR_TRUE; + //prefHeightIntrinsic = PR_TRUE; } @@ -2922,7 +3114,7 @@ nsBoxDebugInner::DisplayDebugInfoFor(nsIPresContext* aPresContext, insideBorder.Deflate(border); - PRBool isHorizontal = mOuter->mInner->mHorizontal; + PRBool isHorizontal = mOuter->mState & NS_STATE_IS_HORIZONTAL; if (!insideBorder.Contains(nsPoint(x,y))) return NS_OK; @@ -2953,48 +3145,54 @@ nsBoxDebugInner::DisplayDebugInfoFor(nsIPresContext* aPresContext, return PR_TRUE; nsCOMPtr content; - mOuter->mInner->GetContentOf(childFrame, getter_AddRefs(content)); + childFrame->GetContent(getter_AddRefs(content)); - nsString id; - mOuter->mContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id); - char idValue[100]; - id.ToCString(idValue,100); + if (content) { + + nsString id; + content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id); + char idValue[100]; + id.ToCString(idValue,100); - nsString kClass; - mOuter->mContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::kClass, kClass); - char kClassValue[100]; - kClass.ToCString(kClassValue,100); + nsString kClass; + content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::kClass, kClass); + char kClassValue[100]; + kClass.ToCString(kClassValue,100); - nsCOMPtr tag; - mOuter->mContent->GetTag(*getter_AddRefs(tag)); - nsString tagString; - tag->ToString(tagString); - char tagValue[100]; - tagString.ToCString(tagValue,100); + nsCOMPtr tag; + content->GetTag(*getter_AddRefs(tag)); + nsString tagString; + tag->ToString(tagString); + char tagValue[100]; + tagString.ToCString(tagValue,100); -#ifdef NS_DEBUG - printf("----- "); - nsFrame::ListTag(stdout, mOuter); - printf(" Tag='%s', id='%s' class='%s'---------------\n", tagValue, idValue, kClassValue); -#endif + #ifdef NS_DEBUG + printf("----- "); + nsFrame::ListTag(stdout, mOuter); + printf(" Tag='%s', id='%s' class='%s'---------------\n", tagValue, idValue, kClassValue); + #endif - content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id); - id.ToCString(idValue,100); + + + content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id); + id.ToCString(idValue,100); - content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::kClass, kClass); - kClass.ToCString(kClassValue,100); + content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::kClass, kClass); + kClass.ToCString(kClassValue,100); - content->GetTag(*getter_AddRefs(tag)); - tag->ToString(tagString); - tagString.ToCString(tagValue,100); + content->GetTag(*getter_AddRefs(tag)); + tag->ToString(tagString); + tagString.ToCString(tagValue,100); #ifdef NS_DEBUG - printf("child #%d: ", count); - nsFrame::ListTag(stdout, childFrame); - printf("Tag='%s', id='%s' class='%s'\n", tagValue, idValue, kClassValue); + printf("child #%d: ", count); + nsFrame::ListTag(stdout, childFrame); + printf("Tag='%s', id='%s' class='%s'\n", tagValue, idValue, kClassValue); #endif + } + mDebugChild = childFrame; nsCalculatedBoxInfoImpl aSize(childFrame); aSize.prefSize.width = NS_INTRINSICSIZE; @@ -3054,36 +3252,38 @@ nsBoxDebugInner::DisplayDebugInfoFor(nsIPresContext* aPresContext, aSize.maxSize.height = max; } - PRInt32 error; - nsAutoString value; + if (content) { + nsAutoString value; + PRInt32 error; + + if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsXULAtoms::flex, value)) + { + value.Trim("%"); + aSize.flex = value.ToInteger(&error); + } + - if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsXULAtoms::flex, value)) - { - value.Trim("%"); - aSize.flex = value.ToInteger(&error); - } + if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::width, value)) + { + float p2t; + aPresContext->GetScaledPixelsToTwips(&p2t); - if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::width, value)) - { - float p2t; - aPresContext->GetScaledPixelsToTwips(&p2t); + value.Trim("%"); - value.Trim("%"); + aSize.prefSize.width = NSIntPixelsToTwips(value.ToInteger(&error), p2t); + } - aSize.prefSize.width = NSIntPixelsToTwips(value.ToInteger(&error), p2t); - } + if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::height, value)) + { + float p2t; + aPresContext->GetScaledPixelsToTwips(&p2t); - if (NS_CONTENT_ATTR_HAS_VALUE == content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::height, value)) - { - float p2t; - aPresContext->GetScaledPixelsToTwips(&p2t); + value.Trim("%"); - value.Trim("%"); + aSize.prefSize.height = NSIntPixelsToTwips(value.ToInteger(&error), p2t); + } - aSize.prefSize.height = NSIntPixelsToTwips(value.ToInteger(&error), p2t); - } - - + } char min[100]; char pref[100]; @@ -3137,11 +3337,15 @@ nsBoxFrame::GetCursor(nsIPresContext* aPresContext, nsPoint newPoint; mInner->TranslateEventCoords(aPresContext, aPoint, newPoint); + /* + nsCOMPtr content; + mInner->GetContentOf(this, getter_AddRefs(content)); + nsString id; - mContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id); + content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::id, id); char idValue[100]; id.ToCString(idValue,100); - +*/ nsRect bounds(0,0,mRect.width, mRect.height); /// printf("----------Box id = %s-----------\n", idValue); @@ -3471,6 +3675,8 @@ nsBoxInfo::Clear() minSize.width = 0; minSize.height = 0; + ascent = 0; + flex = 0; maxSize.width = NS_INTRINSICSIZE; diff --git a/layout/xul/base/src/nsBoxFrame.h b/layout/xul/base/src/nsBoxFrame.h index 555272652542..387b0f575483 100644 --- a/layout/xul/base/src/nsBoxFrame.h +++ b/layout/xul/base/src/nsBoxFrame.h @@ -41,17 +41,21 @@ class nsBoxDebugInner; class nsHTMLReflowCommand; class nsHTMLInfo; +#define NS_FRAME_BOX_SIZE_VALID 0x0001 +#define NS_FRAME_BOX_IS_COLLAPSED 0x0002 +#define NS_FRAME_BOX_NEEDS_RECALC 0x0004 + class nsCalculatedBoxInfo : public nsBoxInfo { public: nsSize calculatedSize; + /* PRBool sizeValid; PRBool collapsed; PRBool needsRecalc; + */ + PRInt16 mFlags; nsCalculatedBoxInfo* next; nsIFrame* frame; - PRBool prefWidthIntrinsic; - PRBool prefHeightIntrinsic; - PRBool neverReflowed; }; class nsInfoList @@ -154,17 +158,28 @@ public: NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); NS_IMETHOD InvalidateCache(nsIFrame* aChild); + enum Halignment { + hAlign_Left, + hAlign_Right, + hAlign_Center, + }; + enum Valignment { + vAlign_Top, + vAlign_Middle, + vAlign_BaseLine, + vAlign_Bottom, + }; protected: nsBoxFrame(); virtual void GetRedefinedMinPrefMax(nsIPresContext* aPresContext, nsIFrame* aFrame, nsCalculatedBoxInfo& aSize); virtual nsresult GetChildBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflowState& aReflowState, nsIFrame* aFrame, nsCalculatedBoxInfo& aSize); - virtual void ComputeChildsNextPosition( nsIFrame* aChild, nscoord& aCurX, nscoord& aCurY, nscoord& aNextX, nscoord& aNextY, const nsSize& aCurrentChildSize, const nsRect& aBoxRect); + virtual void ComputeChildsNextPosition( nsCalculatedBoxInfo* aInfo, nscoord& aCurX, nscoord& aCurY, nscoord& aNextX, nscoord& aNextY, const nsSize& aCurrentChildSize, const nsRect& aBoxRect, nscoord aMaxAscent); virtual nsresult PlaceChildren(nsIPresContext* aPresContext, nsRect& boxRect); - virtual void ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nsCalculatedBoxInfo& aInfo, PRBool* aResized, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason); - virtual void LayoutChildrenInRect(nsRect& size); + virtual void ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nscoord& aMaxAscent, nsCalculatedBoxInfo& aInfo, PRBool* aResized, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason); + virtual void LayoutChildrenInRect(nsRect& aSize, nscoord& aMaxAscent); virtual void AddChildSize(nsBoxInfo& aInfo, nsBoxInfo& aChildInfo); virtual void BoundsCheck(const nsBoxInfo& aBoxInfo, nsRect& aRect); virtual void InvalidateChildren(); @@ -178,10 +193,16 @@ protected: nsresult GenerateDirtyReflowCommand(nsIPresContext* aPresContext, nsIPresShell& aPresShell); - // return true if the alignment is horizontal false if vertical - virtual PRBool GetInitialAlignment(); + + + virtual PRBool GetInitialOrientation(PRBool& aIsHorizontal); + virtual PRBool GetInitialHAlignment(Halignment& aHalign); + virtual PRBool GetInitialVAlignment(Valignment& aValign); + virtual PRBool GetInitialAutoStretch(PRBool& aStretch); + virtual PRBool GetDefaultFlex(PRInt32& aFlex); virtual nsInfoList* GetInfoList(); + private: friend class nsBoxFrameInner; diff --git a/layout/xul/base/src/nsDeckFrame.cpp b/layout/xul/base/src/nsDeckFrame.cpp index daacf19e6e7f..8c008eaee392 100644 --- a/layout/xul/base/src/nsDeckFrame.cpp +++ b/layout/xul/base/src/nsDeckFrame.cpp @@ -269,7 +269,7 @@ nsDeckFrame::AddChildSize(nsBoxInfo& aInfo, nsBoxInfo& aChildInfo) void -nsDeckFrame::ComputeChildsNextPosition( nsIFrame* aChild, nscoord& aCurX, nscoord& aCurY, nscoord& aNextX, nscoord& aNextY, const nsSize& aCurrentChildSize, const nsRect& aBoxRect) +nsDeckFrame::ComputeChildsNextPosition(nsCalculatedBoxInfo* aInfo, nscoord& aCurX, nscoord& aCurY, nscoord& aNextX, nscoord& aNextY, const nsSize& aCurrentChildSize, const nsRect& aBoxRect, nscoord aMaxAscent) { // let everything layout on top of each other. aCurX = aNextX = aBoxRect.x; @@ -350,19 +350,19 @@ nsDeckFrame::DidReflow(nsIPresContext* aPresContext, void -nsDeckFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nsCalculatedBoxInfo& aInfo, PRBool* aResized, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason) +nsDeckFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nscoord& aMaxAscent, nsCalculatedBoxInfo& aInfo, PRBool* aResized, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason) { if (aDesiredSize.width > aRect.width) { aRect.width = aDesiredSize.width; InvalidateChildren(); - LayoutChildrenInRect(aRect); + LayoutChildrenInRect(aRect, aMaxAscent); aReason = "child's width got bigger"; aChangedIndex = aIndex; aFinished = PR_FALSE; } else if (aDesiredSize.height > aRect.height) { aRect.height = aDesiredSize.height; InvalidateChildren(); - LayoutChildrenInRect(aRect); + LayoutChildrenInRect(aRect, aMaxAscent); aReason = "child's height got bigger"; aChangedIndex = aIndex; aFinished = PR_FALSE; @@ -370,16 +370,18 @@ nsDeckFrame::ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, n } void -nsDeckFrame::LayoutChildrenInRect(nsRect& size) +nsDeckFrame::LayoutChildrenInRect(nsRect& aGivenSize, nscoord& aMaxAscent) { nsInfoList* list = GetInfoList(); nsCalculatedBoxInfo* info = list->GetFirst(); while(info) { - info->calculatedSize.width = size.width; - info->calculatedSize.height = size.height; - info->sizeValid = PR_TRUE; + info->calculatedSize.width = aGivenSize.width; + info->calculatedSize.height = aGivenSize.height; + info->mFlags |= NS_FRAME_BOX_SIZE_VALID; info = info->next; } + + aMaxAscent = 0; } diff --git a/layout/xul/base/src/nsDeckFrame.h b/layout/xul/base/src/nsDeckFrame.h index 348e2ffb4e29..033333f41e88 100644 --- a/layout/xul/base/src/nsDeckFrame.h +++ b/layout/xul/base/src/nsDeckFrame.h @@ -83,9 +83,9 @@ public: protected: virtual nsIFrame* GetSelectedFrame(); - virtual void ComputeChildsNextPosition( nsIFrame* aChild, nscoord& aCurX, nscoord& aCurY, nscoord& aNextX, nscoord& aNextY, const nsSize& aCurrentChildSize, const nsRect& aBoxRect); - virtual void ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nsCalculatedBoxInfo& aInfo, PRBool* aResized, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason); - virtual void LayoutChildrenInRect(nsRect& size); + virtual void ComputeChildsNextPosition( nsCalculatedBoxInfo* aInfo, nscoord& aCurX, nscoord& aCurY, nscoord& aNextX, nscoord& aNextY, const nsSize& aCurrentChildSize, const nsRect& aBoxRect, nscoord aMaxAscent); + virtual void ChildResized(nsIFrame* aFrame, nsHTMLReflowMetrics& aDesiredSize, nsRect& aRect, nscoord& aMaxAscent, nsCalculatedBoxInfo& aInfo, PRBool* aResized, nscoord& aChangedIndex, PRBool& aFinished, nscoord aIndex, nsString& aReason); + virtual void LayoutChildrenInRect(nsRect& aSize, nscoord& aMaxAscent); virtual void AddChildSize(nsBoxInfo& aInfo, nsBoxInfo& aChildInfo); diff --git a/layout/xul/base/src/nsGroupBoxFrame.cpp b/layout/xul/base/src/nsGroupBoxFrame.cpp new file mode 100644 index 000000000000..296ca2846966 --- /dev/null +++ b/layout/xul/base/src/nsGroupBoxFrame.cpp @@ -0,0 +1,320 @@ +/* -*- 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.1 (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.org 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. + * + * Contributor(s): + */ + +// YY need to pass isMultiple before create called + +/* +//#include "nsFormControlFrame.h" +#include "nsHTMLContainerFrame.h" +#include "nsLegendFrame.h" +#include "nsIDOMNode.h" +#include "nsIDOMHTMLFieldSetElement.h" +#include "nsIDOMHTMLLegendElement.h" +//#include "nsIDOMHTMLCollection.h" +#include "nsIContent.h" +#include "nsIFrame.h" +#include "nsISupports.h" +#include "nsIAtom.h" +#include "nsIPresContext.h" +#include "nsIHTMLContent.h" +#include "nsHTMLIIDs.h" +#include "nsHTMLParts.h" +#include "nsHTMLAtoms.h" +#include "nsIStyleContext.h" +#include "nsStyleConsts.h" +#include "nsStyleUtil.h" +#include "nsFont.h" +#include "nsCOMPtr.h" +*/ + +#include "nsCSSRendering.h" +#include "nsIStyleContext.h" +#include "nsBoxFrame.h" + +class nsTitledBoxFrame : public nsBoxFrame { +public: + + nsTitledBoxFrame(); + + NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext, + nsIAtom* aListName, + nsIFrame* aChildList); + + NS_METHOD Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer); + +#ifdef DEBUG + NS_IMETHOD GetFrameName(nsString& aResult) const { + return MakeFrameName("GroupBoxFrame", aResult); + } +#endif + + NS_IMETHOD Reflow(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus); + + virtual PRBool GetInitialOrientation(PRBool& aHorizontal) { aHorizontal = PR_FALSE; return PR_TRUE; } + + nsIFrame* GetGroupTitle(nsIPresContext* aPresContext, nsRect& aRect); + +}; + +class nsTitledBoxInnerFrame : public nsBoxFrame { +public: + + nsTitledBoxInnerFrame() {} + + +#ifdef DEBUG + NS_IMETHOD GetFrameName(nsString& aResult) const { + return MakeFrameName("TitledBoxFrameInner", aResult); + } +#endif + + // we are always flexible + virtual PRBool GetDefaultFlex(PRInt32& aFlex) { aFlex = 1; return PR_TRUE; } + +}; + +nsresult +NS_NewTitledBoxInnerFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) +{ + NS_PRECONDITION(aNewFrame, "null OUT ptr"); + if (nsnull == aNewFrame) { + return NS_ERROR_NULL_POINTER; + } + nsTitledBoxInnerFrame* it = new (aPresShell) nsTitledBoxInnerFrame; + if (!it) { + return NS_ERROR_OUT_OF_MEMORY; + } + + *aNewFrame = it; + return NS_OK; +} + +nsresult +NS_NewTitledBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) +{ + NS_PRECONDITION(aNewFrame, "null OUT ptr"); + if (nsnull == aNewFrame) { + return NS_ERROR_NULL_POINTER; + } + nsTitledBoxFrame* it = new (aPresShell) nsTitledBoxFrame; + if (!it) { + return NS_ERROR_OUT_OF_MEMORY; + } + + *aNewFrame = it; + return NS_OK; +} + +nsTitledBoxFrame::nsTitledBoxFrame() +{ +} + + +NS_IMETHODIMP +nsTitledBoxFrame::SetInitialChildList(nsIPresContext* aPresContext, + nsIAtom* aListName, + nsIFrame* aChildList) +{ + // Queue up the frames for the content frame + return nsBoxFrame::SetInitialChildList(aPresContext, nsnull, aChildList); +} + +// this is identical to nsHTMLContainerFrame::Paint except for the background and border. +NS_IMETHODIMP +nsTitledBoxFrame::Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ + if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { + // Paint our background and border + const nsStyleDisplay* disp = + (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display); + + if (disp->mVisible == NS_STYLE_VISIBILITY_VISIBLE && mRect.width && mRect.height) { + PRIntn skipSides = GetSkipSides(); + const nsStyleColor* color = + (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); + const nsStyleSpacing* spacing = + (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing); + + nsMargin border; + if (!spacing->GetBorder(border)) { + NS_NOTYETIMPLEMENTED("percentage border"); + } + + nscoord yoff = 0; + + nsRect titleRect; + nsIFrame* titleFrame = GetGroupTitle(aPresContext, titleRect); + + if (titleFrame) { + // if the border is smaller than the legend. Move the border down + // to be centered on the legend. + const nsStyleSpacing* titleSpacing; + titleFrame->GetStyleData(eStyleStruct_Spacing, + (const nsStyleStruct*&) titleSpacing); + + nsMargin titleMargin; + titleSpacing->GetMargin(titleMargin); + titleRect.Inflate(titleMargin); + + if (border.top < titleRect.height) + yoff = (titleRect.height - border.top)/2 + titleRect.y; + } + + nsRect rect(0, yoff, mRect.width, mRect.height - yoff); + + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *color, *spacing, 0, 0); + + + if (titleFrame) { + + // we should probably use PaintBorderEdges to do this but for now just use clipping + // to achieve the same effect. + PRBool clipState; + + // draw left side + nsRect clipRect(rect); + clipRect.width = titleRect.x - rect.x; + clipRect.height = border.top; + + aRenderingContext.PushState(); + aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect, clipState); + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *spacing, mStyleContext, skipSides); + + aRenderingContext.PopState(clipState); + + + // draw right side + clipRect = rect; + clipRect.x = titleRect.x + titleRect.width; + clipRect.width -= (titleRect.x + titleRect.width); + clipRect.height = border.top; + + aRenderingContext.PushState(); + aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect, clipState); + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *spacing, mStyleContext, skipSides); + + aRenderingContext.PopState(clipState); + + + + // draw bottom + + clipRect = rect; + clipRect.y += border.top; + clipRect.height = mRect.height - (yoff + border.top); + + aRenderingContext.PushState(); + aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect, clipState); + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *spacing, mStyleContext, skipSides); + + aRenderingContext.PopState(clipState); + + } else { + + + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, + aDirtyRect, nsRect(0,0,mRect.width, mRect.height), *spacing, mStyleContext, skipSides); + } + } + } + + PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + +#ifdef DEBUG + if ((NS_FRAME_PAINT_LAYER_DEBUG == aWhichLayer) && GetShowFrameBorders()) { + nsIView* view; + GetView(aPresContext, &view); + if (nsnull != view) { + aRenderingContext.SetColor(NS_RGB(0,0,255)); + } + else { + aRenderingContext.SetColor(NS_RGB(255,0,0)); + } + aRenderingContext.DrawRect(0, 0, mRect.width, mRect.height); + } +#endif + return NS_OK; +} + +nsIFrame* +nsTitledBoxFrame::GetGroupTitle(nsIPresContext* aPresContext, nsRect& aTitleRect) +{ + // if we only have one child fail + nsIFrame* frame = mFrames.FirstChild(); + nsIFrame* next = nsnull; + frame->GetNextSibling(&next); + if (!next) + return nsnull; + + // if we have more than one child. The first is our baby. + // then get the first child inside. + nsIFrame* child; + frame->FirstChild(aPresContext, nsnull, &child); + + if (child) { + // convert to our coordinates. + nsRect parentRect; + frame->GetRect(parentRect); + child->GetRect(aTitleRect); + aTitleRect.x += parentRect.x; + aTitleRect.y += parentRect.y; + } + + return child; +} + +NS_IMETHODIMP +nsTitledBoxFrame::Reflow(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + if (aReflowState.mComputedBorderPadding.top != 0) + { + nsHTMLReflowState newState(aReflowState); + + if (newState.mComputedHeight != NS_INTRINSICSIZE) + newState.mComputedHeight += aReflowState.mComputedBorderPadding.top; + + // remove the border from border padding + ((nsMargin&)newState.mComputedBorderPadding).top = 0; + ((nsMargin&)newState.mComputedPadding).top = 0; + + // reflow us again with the correct values. + return Reflow(aPresContext, aDesiredSize, newState, aStatus); + } + + return nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); +} \ No newline at end of file diff --git a/layout/xul/base/src/nsIBox.h b/layout/xul/base/src/nsIBox.h index 53b9d98c5e2f..52fe136c78d9 100644 --- a/layout/xul/base/src/nsIBox.h +++ b/layout/xul/base/src/nsIBox.h @@ -45,6 +45,7 @@ public: nsSize minSize; nsSize maxSize; PRInt32 flex; + nscoord ascent; nsBoxInfo(); virtual void Clear(); diff --git a/layout/xul/base/src/nsMenuPopupFrame.cpp b/layout/xul/base/src/nsMenuPopupFrame.cpp index c7a9bab2eb50..9f527854295d 100644 --- a/layout/xul/base/src/nsMenuPopupFrame.cpp +++ b/layout/xul/base/src/nsMenuPopupFrame.cpp @@ -171,16 +171,11 @@ nsMenuPopupFrame::Init(nsIPresContext* aPresContext, } PRBool -nsMenuPopupFrame::GetInitialAlignment() +nsMenuPopupFrame::GetInitialOrientation(PRBool& aIsHorizontal) { - // by default we are vertical unless horizontal is specifically specified - nsString value; - - mContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, value); - if (value.EqualsIgnoreCase("horizontal")) - return PR_TRUE; - else - return PR_FALSE; + // by default we are vertical + aIsHorizontal = PR_FALSE; + return nsBoxFrame::GetInitialOrientation(aIsHorizontal); } void diff --git a/layout/xul/base/src/nsMenuPopupFrame.h b/layout/xul/base/src/nsMenuPopupFrame.h index 589747fb7207..9d0ba02feab3 100644 --- a/layout/xul/base/src/nsMenuPopupFrame.h +++ b/layout/xul/base/src/nsMenuPopupFrame.h @@ -130,7 +130,7 @@ public: protected: // return true if the alignment is horizontal false if vertical - virtual PRBool GetInitialAlignment(); + virtual PRBool GetInitialOrientation(PRBool& aIsHorizontal); // given x,y in client coordinates, compensate for nested documents like framesets. void AdjustClientXYForNestedDocuments ( nsIDOMXULDocument* inPopupDoc, nsIPresShell* inPopupShell, diff --git a/layout/xul/base/src/nsSliderFrame.cpp b/layout/xul/base/src/nsSliderFrame.cpp index 037fd2049523..d91699c560d1 100644 --- a/layout/xul/base/src/nsSliderFrame.cpp +++ b/layout/xul/base/src/nsSliderFrame.cpp @@ -1016,7 +1016,7 @@ NS_IMETHODIMP_(void) nsSliderFrame::Notify(nsITimer *timer) if (thumbRect.y < mClickPoint.y) stop = PR_TRUE; } else { - if (thumbRect.y + thumbRect.width > mClickPoint.y) + if (thumbRect.y + thumbRect.height > mClickPoint.y) stop = PR_TRUE; } } diff --git a/layout/xul/base/src/nsSplitterFrame.cpp b/layout/xul/base/src/nsSplitterFrame.cpp index 96d3a2e13523..eb2506828296 100644 --- a/layout/xul/base/src/nsSplitterFrame.cpp +++ b/layout/xul/base/src/nsSplitterFrame.cpp @@ -343,7 +343,9 @@ nsSplitterFrame::Init(nsIPresContext* aPresContext, nsHTMLContainerFrame::CreateViewForFrame(aPresContext,this,aContext,PR_TRUE); nsIView* view; GetView(aPresContext, &view); -#if 1 + +// currently this only works on win32 +#ifndef WIN32 view->SetContentTransparency(PR_TRUE); view->SetZIndex(kMaxZ); /* @@ -375,7 +377,7 @@ nsSplitterFrame::Init(nsIPresContext* aPresContext, } PRBool -nsSplitterFrame::GetInitialAlignment() +nsSplitterFrame::GetInitialOrientation(PRBool& aIsHorizontal) { // find the box we are in nsIFrame* box = nsnull; @@ -385,15 +387,10 @@ nsSplitterFrame::GetInitialAlignment() if (box == nsnull) nsScrollbarButtonFrame::GetParentWithTag(nsXULAtoms::window, this, box); - // see if the box is horizontal or vertical + // see if the box is horizontal or vertical we are the opposite if (box) { - nsCOMPtr content; - box->GetContent(getter_AddRefs(content)); - - nsString value; - content->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, value); - if (value.EqualsIgnoreCase("vertical")) - return PR_TRUE; + aIsHorizontal = !((nsBoxFrame*)box)->IsHorizontal(); + return PR_TRUE; } return PR_FALSE; diff --git a/layout/xul/base/src/nsSplitterFrame.h b/layout/xul/base/src/nsSplitterFrame.h index a5d4fdfafb61..ccb744b713ed 100644 --- a/layout/xul/base/src/nsSplitterFrame.h +++ b/layout/xul/base/src/nsSplitterFrame.h @@ -95,8 +95,7 @@ public: NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext, const nsPoint& aPoint, nsIFrame** aFrame); - // return true if the alignment is horizontal false if vertical - virtual PRBool GetInitialAlignment(); + virtual PRBool GetInitialOrientation(PRBool& aIsHorizontal); private: diff --git a/layout/xul/base/src/nsTitleFrame.cpp b/layout/xul/base/src/nsTitleFrame.cpp new file mode 100644 index 000000000000..bb658b667029 --- /dev/null +++ b/layout/xul/base/src/nsTitleFrame.cpp @@ -0,0 +1,92 @@ +/* -*- 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.1 (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.org 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. + * + * Contributor(s): + */ + +// YY need to pass isMultiple before create called + +#include "nsTitleFrame.h" + +/* +#include "nsTitleFrame.h" +#include "nsIContent.h" +#include "nsIFrame.h" +#include "nsISupports.h" +#include "nsIAtom.h" +#include "nsIHTMLContent.h" +#include "nsHTMLIIDs.h" +#include "nsHTMLParts.h" +#include "nsHTMLAtoms.h" +#include "nsIStyleContext.h" +#include "nsStyleConsts.h" +#include "nsStyleUtil.h" +#include "nsFont.h" +#include "nsFormControlFrame.h" +*/ + +static NS_DEFINE_IID(kTitleFrameCID, NS_TITLE_FRAME_CID); + +nsresult +NS_NewTitleFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) +{ + NS_PRECONDITION(aNewFrame, "null OUT ptr"); + if (nsnull == aNewFrame) { + return NS_ERROR_NULL_POINTER; + } + nsTitleFrame* it = new (aPresShell) nsTitleFrame; + if (!it) { + return NS_ERROR_OUT_OF_MEMORY; + } + *aNewFrame = it; + return NS_OK; +} + +nsTitleFrame::nsTitleFrame() +{ +} + +nsTitleFrame::~nsTitleFrame() +{ +} + +// Frames are not refcounted, no need to AddRef +NS_IMETHODIMP +nsTitleFrame::QueryInterface(REFNSIID aIID, void** aInstancePtrResult) +{ + NS_PRECONDITION(nsnull != aInstancePtrResult, "null pointer"); + if (nsnull == aInstancePtrResult) { + return NS_ERROR_NULL_POINTER; + } + if (aIID.Equals(kTitleFrameCID)) { + *aInstancePtrResult = (void*) ((nsTitleFrame*)this); + return NS_OK; + } + return nsBoxFrame::QueryInterface(aIID, aInstancePtrResult); +} + + + +#ifdef NS_DEBUG +NS_IMETHODIMP +nsTitleFrame::GetFrameName(nsString& aResult) const +{ + return MakeFrameName("Title", aResult); +} +#endif diff --git a/layout/xul/base/src/nsTitledBoxFrame.cpp b/layout/xul/base/src/nsTitledBoxFrame.cpp new file mode 100644 index 000000000000..296ca2846966 --- /dev/null +++ b/layout/xul/base/src/nsTitledBoxFrame.cpp @@ -0,0 +1,320 @@ +/* -*- 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.1 (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.org 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. + * + * Contributor(s): + */ + +// YY need to pass isMultiple before create called + +/* +//#include "nsFormControlFrame.h" +#include "nsHTMLContainerFrame.h" +#include "nsLegendFrame.h" +#include "nsIDOMNode.h" +#include "nsIDOMHTMLFieldSetElement.h" +#include "nsIDOMHTMLLegendElement.h" +//#include "nsIDOMHTMLCollection.h" +#include "nsIContent.h" +#include "nsIFrame.h" +#include "nsISupports.h" +#include "nsIAtom.h" +#include "nsIPresContext.h" +#include "nsIHTMLContent.h" +#include "nsHTMLIIDs.h" +#include "nsHTMLParts.h" +#include "nsHTMLAtoms.h" +#include "nsIStyleContext.h" +#include "nsStyleConsts.h" +#include "nsStyleUtil.h" +#include "nsFont.h" +#include "nsCOMPtr.h" +*/ + +#include "nsCSSRendering.h" +#include "nsIStyleContext.h" +#include "nsBoxFrame.h" + +class nsTitledBoxFrame : public nsBoxFrame { +public: + + nsTitledBoxFrame(); + + NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext, + nsIAtom* aListName, + nsIFrame* aChildList); + + NS_METHOD Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer); + +#ifdef DEBUG + NS_IMETHOD GetFrameName(nsString& aResult) const { + return MakeFrameName("GroupBoxFrame", aResult); + } +#endif + + NS_IMETHOD Reflow(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus); + + virtual PRBool GetInitialOrientation(PRBool& aHorizontal) { aHorizontal = PR_FALSE; return PR_TRUE; } + + nsIFrame* GetGroupTitle(nsIPresContext* aPresContext, nsRect& aRect); + +}; + +class nsTitledBoxInnerFrame : public nsBoxFrame { +public: + + nsTitledBoxInnerFrame() {} + + +#ifdef DEBUG + NS_IMETHOD GetFrameName(nsString& aResult) const { + return MakeFrameName("TitledBoxFrameInner", aResult); + } +#endif + + // we are always flexible + virtual PRBool GetDefaultFlex(PRInt32& aFlex) { aFlex = 1; return PR_TRUE; } + +}; + +nsresult +NS_NewTitledBoxInnerFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) +{ + NS_PRECONDITION(aNewFrame, "null OUT ptr"); + if (nsnull == aNewFrame) { + return NS_ERROR_NULL_POINTER; + } + nsTitledBoxInnerFrame* it = new (aPresShell) nsTitledBoxInnerFrame; + if (!it) { + return NS_ERROR_OUT_OF_MEMORY; + } + + *aNewFrame = it; + return NS_OK; +} + +nsresult +NS_NewTitledBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame) +{ + NS_PRECONDITION(aNewFrame, "null OUT ptr"); + if (nsnull == aNewFrame) { + return NS_ERROR_NULL_POINTER; + } + nsTitledBoxFrame* it = new (aPresShell) nsTitledBoxFrame; + if (!it) { + return NS_ERROR_OUT_OF_MEMORY; + } + + *aNewFrame = it; + return NS_OK; +} + +nsTitledBoxFrame::nsTitledBoxFrame() +{ +} + + +NS_IMETHODIMP +nsTitledBoxFrame::SetInitialChildList(nsIPresContext* aPresContext, + nsIAtom* aListName, + nsIFrame* aChildList) +{ + // Queue up the frames for the content frame + return nsBoxFrame::SetInitialChildList(aPresContext, nsnull, aChildList); +} + +// this is identical to nsHTMLContainerFrame::Paint except for the background and border. +NS_IMETHODIMP +nsTitledBoxFrame::Paint(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer) +{ + if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { + // Paint our background and border + const nsStyleDisplay* disp = + (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display); + + if (disp->mVisible == NS_STYLE_VISIBILITY_VISIBLE && mRect.width && mRect.height) { + PRIntn skipSides = GetSkipSides(); + const nsStyleColor* color = + (const nsStyleColor*)mStyleContext->GetStyleData(eStyleStruct_Color); + const nsStyleSpacing* spacing = + (const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing); + + nsMargin border; + if (!spacing->GetBorder(border)) { + NS_NOTYETIMPLEMENTED("percentage border"); + } + + nscoord yoff = 0; + + nsRect titleRect; + nsIFrame* titleFrame = GetGroupTitle(aPresContext, titleRect); + + if (titleFrame) { + // if the border is smaller than the legend. Move the border down + // to be centered on the legend. + const nsStyleSpacing* titleSpacing; + titleFrame->GetStyleData(eStyleStruct_Spacing, + (const nsStyleStruct*&) titleSpacing); + + nsMargin titleMargin; + titleSpacing->GetMargin(titleMargin); + titleRect.Inflate(titleMargin); + + if (border.top < titleRect.height) + yoff = (titleRect.height - border.top)/2 + titleRect.y; + } + + nsRect rect(0, yoff, mRect.width, mRect.height - yoff); + + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *color, *spacing, 0, 0); + + + if (titleFrame) { + + // we should probably use PaintBorderEdges to do this but for now just use clipping + // to achieve the same effect. + PRBool clipState; + + // draw left side + nsRect clipRect(rect); + clipRect.width = titleRect.x - rect.x; + clipRect.height = border.top; + + aRenderingContext.PushState(); + aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect, clipState); + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *spacing, mStyleContext, skipSides); + + aRenderingContext.PopState(clipState); + + + // draw right side + clipRect = rect; + clipRect.x = titleRect.x + titleRect.width; + clipRect.width -= (titleRect.x + titleRect.width); + clipRect.height = border.top; + + aRenderingContext.PushState(); + aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect, clipState); + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *spacing, mStyleContext, skipSides); + + aRenderingContext.PopState(clipState); + + + + // draw bottom + + clipRect = rect; + clipRect.y += border.top; + clipRect.height = mRect.height - (yoff + border.top); + + aRenderingContext.PushState(); + aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect, clipState); + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *spacing, mStyleContext, skipSides); + + aRenderingContext.PopState(clipState); + + } else { + + + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, + aDirtyRect, nsRect(0,0,mRect.width, mRect.height), *spacing, mStyleContext, skipSides); + } + } + } + + PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + +#ifdef DEBUG + if ((NS_FRAME_PAINT_LAYER_DEBUG == aWhichLayer) && GetShowFrameBorders()) { + nsIView* view; + GetView(aPresContext, &view); + if (nsnull != view) { + aRenderingContext.SetColor(NS_RGB(0,0,255)); + } + else { + aRenderingContext.SetColor(NS_RGB(255,0,0)); + } + aRenderingContext.DrawRect(0, 0, mRect.width, mRect.height); + } +#endif + return NS_OK; +} + +nsIFrame* +nsTitledBoxFrame::GetGroupTitle(nsIPresContext* aPresContext, nsRect& aTitleRect) +{ + // if we only have one child fail + nsIFrame* frame = mFrames.FirstChild(); + nsIFrame* next = nsnull; + frame->GetNextSibling(&next); + if (!next) + return nsnull; + + // if we have more than one child. The first is our baby. + // then get the first child inside. + nsIFrame* child; + frame->FirstChild(aPresContext, nsnull, &child); + + if (child) { + // convert to our coordinates. + nsRect parentRect; + frame->GetRect(parentRect); + child->GetRect(aTitleRect); + aTitleRect.x += parentRect.x; + aTitleRect.y += parentRect.y; + } + + return child; +} + +NS_IMETHODIMP +nsTitledBoxFrame::Reflow(nsIPresContext* aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + const nsHTMLReflowState& aReflowState, + nsReflowStatus& aStatus) +{ + if (aReflowState.mComputedBorderPadding.top != 0) + { + nsHTMLReflowState newState(aReflowState); + + if (newState.mComputedHeight != NS_INTRINSICSIZE) + newState.mComputedHeight += aReflowState.mComputedBorderPadding.top; + + // remove the border from border padding + ((nsMargin&)newState.mComputedBorderPadding).top = 0; + ((nsMargin&)newState.mComputedPadding).top = 0; + + // reflow us again with the correct values. + return Reflow(aPresContext, aDesiredSize, newState, aStatus); + } + + return nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus); +} \ No newline at end of file diff --git a/layout/xul/base/src/nsTitledButtonFrame.cpp b/layout/xul/base/src/nsTitledButtonFrame.cpp index 88f831dd6859..0f5a2a033026 100644 --- a/layout/xul/base/src/nsTitledButtonFrame.cpp +++ b/layout/xul/base/src/nsTitledButtonFrame.cpp @@ -626,7 +626,7 @@ nsTitledButtonFrame::LayoutTitleAndImage(nsIPresContext* aPresContext, void nsTitledButtonFrame::GetTextSize(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, - const nsString& aString, nsSize& aSize) + const nsString& aString, nsSize& aSize, nscoord& aAscent) { const nsStyleFont* fontStyle = (const nsStyleFont*)mStyleContext->GetStyleData(eStyleStruct_Font); @@ -638,6 +638,7 @@ nsTitledButtonFrame::GetTextSize(nsIPresContext* aPresContext, nsIRenderingConte fontMet->GetHeight(aSize.height); aRenderingContext.SetFont(fontMet); aRenderingContext.GetWidth(aString, aSize.width); + fontMet->GetMaxAscent(aAscent); } void @@ -987,16 +988,19 @@ nsTitledButtonFrame::GetDesiredSize(nsIPresContext* aPresContext, // if either the width or the height was not computed use our intrinsic size if (aReflowState.mComputedWidth != NS_INTRINSICSIZE) - //if (aReflowState.mComputedWidth > info.minSize.width) aDesiredSize.width = aReflowState.mComputedWidth; - //else - // aDesiredSize.width = info.minSize.width; - if (aReflowState.mComputedHeight != NS_INTRINSICSIZE) - //if (aReflowState.mComputedHeight > info.minSize.height) + if (aReflowState.mComputedHeight != NS_INTRINSICSIZE) { aDesiredSize.height = aReflowState.mComputedHeight; - //else -// aDesiredSize.height = info.minSize.height; + nscoord descent = info.prefSize.height - info.ascent; + aDesiredSize.ascent = aDesiredSize.height - descent; + if (aDesiredSize.ascent < 0) + aDesiredSize.ascent = 0; + } else { + aDesiredSize.ascent = info.ascent; + } + + } @@ -1451,8 +1455,11 @@ nsTitledButtonFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflow // depending on the type of alignment add in the space for the text nsSize size; + nscoord ascent = 0; GetTextSize(aPresContext, *aReflowState.rendContext, - mTitle, size); + mTitle, size, ascent); + + aSize.ascent = ascent; switch (mAlign) { case NS_SIDE_TOP: @@ -1510,6 +1517,8 @@ nsTitledButtonFrame::GetBoxInfo(nsIPresContext* aPresContext, const nsHTMLReflow aSize.minSize.width += focusBorder.left + focusBorder.right; aSize.minSize.height += focusBorder.top + focusBorder.bottom; + ascent += focusBorder.top; + return NS_OK; } diff --git a/layout/xul/base/src/nsTitledButtonFrame.h b/layout/xul/base/src/nsTitledButtonFrame.h index 810db35d19be..eef6a12c70d2 100644 --- a/layout/xul/base/src/nsTitledButtonFrame.h +++ b/layout/xul/base/src/nsTitledButtonFrame.h @@ -133,7 +133,7 @@ protected: virtual void CalculateTitleForWidth(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, nscoord aWidth); - virtual void GetTextSize(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsString& aString, nsSize& aSize); + virtual void GetTextSize(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsString& aString, nsSize& aSize, nscoord& aAscent); virtual void SetDisabled(nsAutoString aDisabled); diff --git a/layout/xul/base/src/nsToolboxFrame.cpp b/layout/xul/base/src/nsToolboxFrame.cpp index 75fc32e5e2ea..5e6a36a57326 100644 --- a/layout/xul/base/src/nsToolboxFrame.cpp +++ b/layout/xul/base/src/nsToolboxFrame.cpp @@ -109,16 +109,11 @@ nsToolboxFrame :: nsToolboxFrame ( ) PRBool -nsToolboxFrame::GetInitialAlignment() +nsToolboxFrame::GetInitialOrientation(PRBool& aIsHorizontal) { - // by default we are vertical unless horizontal is specifically specified - nsString value; - - mContent->GetAttribute(kNameSpaceID_None, nsHTMLAtoms::align, value); - if (value.EqualsIgnoreCase("horizontal")) - return PR_TRUE; - else - return PR_FALSE; + // by default we are vertical. + aIsHorizontal = PR_FALSE; + return nsBoxFrame::GetInitialOrientation(aIsHorizontal); } // // nsToolboxFrame dstr diff --git a/layout/xul/base/src/nsToolboxFrame.h b/layout/xul/base/src/nsToolboxFrame.h index d003d663688e..ab32191ba6e2 100644 --- a/layout/xul/base/src/nsToolboxFrame.h +++ b/layout/xul/base/src/nsToolboxFrame.h @@ -128,7 +128,7 @@ protected: nsToolboxFrame(); virtual ~nsToolboxFrame(); - virtual PRBool GetInitialAlignment(); + virtual PRBool GetInitialOrientation(PRBool& aIsHorizontal); virtual void UpdateStyles(nsIPresContext* aPresContext); virtual void CalculateGrippies(nsIPresContext* aPresContext); diff --git a/layout/xul/content/src/nsXULAtomList.h b/layout/xul/content/src/nsXULAtomList.h index a80f46c6d89a..9b559c2b966b 100644 --- a/layout/xul/content/src/nsXULAtomList.h +++ b/layout/xul/content/src/nsXULAtomList.h @@ -99,6 +99,11 @@ XUL_ATOM(box, "box") XUL_ATOM(flex, "flex") XUL_ATOM(spring, "spring") XUL_ATOM(orient, "orient") +XUL_ATOM(autostretch, "autostretch") + +XUL_ATOM(titledbox, "titledbox") +XUL_ATOM(title, "title") +XUL_ATOM(titledboxContentPseudo, ":titledbox-content") XUL_ATOM(deck, "deck") XUL_ATOM(tabcontrol, "tabcontrol") diff --git a/xpfe/components/prefwindow/resources/content/pref-advanced.xul b/xpfe/components/prefwindow/resources/content/pref-advanced.xul index 08bc09e387fc..0d2ed4380f9b 100644 --- a/xpfe/components/prefwindow/resources/content/pref-advanced.xul +++ b/xpfe/components/prefwindow/resources/content/pref-advanced.xul @@ -35,8 +35,8 @@ - - + + @@ -44,7 +44,7 @@ &autoLoadImgCheck.label; - + @@ -52,7 +52,7 @@ &enbJavaCheck.label; - + @@ -60,7 +60,7 @@ &enbJsCheck.label; - + @@ -68,7 +68,7 @@ &enbJsCheck.labelforMailNNews; - + @@ -76,7 +76,7 @@ &enbCssCheck.label; - + @@ -84,7 +84,7 @@ &sendAddFtpCheck.label; - + @@ -92,7 +92,7 @@ &remSignCheck.label; - + @@ -100,6 +100,6 @@ &remWalletCheck.label; - + diff --git a/xpfe/components/prefwindow/resources/content/pref-appearance.xul b/xpfe/components/prefwindow/resources/content/pref-appearance.xul index 995ed2a8a08b..316d21797a58 100644 --- a/xpfe/components/prefwindow/resources/content/pref-appearance.xul +++ b/xpfe/components/prefwindow/resources/content/pref-appearance.xul @@ -37,8 +37,8 @@ - - &onStartLegend.label; + + <text value="&onStartLegend.label;"/> @@ -60,10 +60,10 @@ &compCheck.label; - + - - &showToolsLegend.label; + + <text value="&showToolsLegend.label;"/> - - + + diff --git a/xpfe/components/prefwindow/resources/content/pref-cache.xul b/xpfe/components/prefwindow/resources/content/pref-cache.xul index efd9e77703f7..392a7f580f9f 100644 --- a/xpfe/components/prefwindow/resources/content/pref-cache.xul +++ b/xpfe/components/prefwindow/resources/content/pref-cache.xul @@ -23,7 +23,7 @@ - - - + + &cachePara; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + - - &docCache; - - + + + + + &oncePsessionRadio.label; - + &everyTimeRadio.label; - + @@ -118,7 +158,7 @@ - + diff --git a/xpfe/components/prefwindow/resources/content/pref-colors.xul b/xpfe/components/prefwindow/resources/content/pref-colors.xul index c60b9760e0d1..e60e1b531078 100644 --- a/xpfe/components/prefwindow/resources/content/pref-colors.xul +++ b/xpfe/components/prefwindow/resources/content/pref-colors.xul @@ -24,7 +24,7 @@ - - - &color; - + + <html:div> &color;</html:div> + &text; - + @@ -56,12 +56,12 @@ - + &background; - + - + @@ -77,18 +77,18 @@ &useWinColorsCheck.label; - + - - &links; - + + <text value="&links;"/> + &unvisit; - + - - + + @@ -96,12 +96,12 @@ - + &visit; - + - + @@ -117,24 +117,25 @@ &underLinksCheck.label; - + - - &someProvColors; - + + <text value="&someProvColors;"/> + &alwaysUseDocColors.label; - + &ignoreDocColors.label; - + + diff --git a/xpfe/components/prefwindow/resources/content/pref-composer.xul b/xpfe/components/prefwindow/resources/content/pref-composer.xul index c79136d83d0b..04ba2d2fb6d2 100644 --- a/xpfe/components/prefwindow/resources/content/pref-composer.xul +++ b/xpfe/components/prefwindow/resources/content/pref-composer.xul @@ -25,7 +25,7 @@ - - - - &authorName; - - - + + + + + + - - &pageColorHeader; - - - + + <text value="&pageColorHeader;"/> + + &NormalText.label; @@ -134,7 +133,7 @@ - + &NormalText.label; @@ -146,14 +145,15 @@ - + - + + - + - - + + diff --git a/xpfe/components/prefwindow/resources/content/pref-cookies.xul b/xpfe/components/prefwindow/resources/content/pref-cookies.xul index ea459d9f867c..68e4a6f87c03 100644 --- a/xpfe/components/prefwindow/resources/content/pref-cookies.xul +++ b/xpfe/components/prefwindow/resources/content/pref-cookies.xul @@ -23,7 +23,7 @@ - - - &cookies; - - - - - &cookieDetails; - - - - - - - - - - - &accAllCookiesRadio.label; - - - - - - - - - - &accpOrgCookiesRadio.label; - - - - - - - - - - &disCookRadio.label; - - - - - - - - - &warnCookCheck.label; - - - - - - + + <text value="&cookies;"/> + &cookieDetails; + + + + + + + &accAllCookiesRadio.label; + + + + + + + + &accpOrgCookiesRadio.label; + + + + + + + + &disCookRadio.label; + + + + + + + + + &warnCookCheck.label; + + + + + - - + diff --git a/xpfe/components/prefwindow/resources/content/pref-debug.xul b/xpfe/components/prefwindow/resources/content/pref-debug.xul index 74db64c69fc0..3f9028fc8fcb 100644 --- a/xpfe/components/prefwindow/resources/content/pref-debug.xul +++ b/xpfe/components/prefwindow/resources/content/pref-debug.xul @@ -37,9 +37,8 @@ - - - &widgetRendering.label; + + <text value="&widgetRendering.label;"/> - - + + + + &debugXULBox.label; + + + + - - - &debugEventDebugging.label; + + <text value="&debugEventDebugging.label;"/> @@ -120,12 +125,10 @@ - - + - - - &debugMiscellaneous.label; + + <text value="&debugMiscellaneous.label;"/> @@ -156,8 +159,7 @@ &debugShowAboutAsStupidModalWindow.label; - - + diff --git a/xpfe/components/prefwindow/resources/content/pref-editing.xul b/xpfe/components/prefwindow/resources/content/pref-editing.xul index c8c574510606..77cbe22a9245 100644 --- a/xpfe/components/prefwindow/resources/content/pref-editing.xul +++ b/xpfe/components/prefwindow/resources/content/pref-editing.xul @@ -25,7 +25,7 @@ - - - - &maintainTableStructure.label; - - - Key Mappings - + + + + &maintainTableStructure.label; + + + + <text value="Key Mappings"/> + &returnkey.label; - + &returnkeyradio0.label; - + &returnkeyradio1.label; - + &returnkeyradio2.label; - + @@ -121,38 +121,38 @@ - + &enterkey.label; - + &returnkeyradio0.label; - + &returnkeyradio1.label; - + &returnkeyradio2.label; - + &returnkeyradio3.label; - + diff --git a/xpfe/components/prefwindow/resources/content/pref-fonts.xul b/xpfe/components/prefwindow/resources/content/pref-fonts.xul index ccfce5a284f2..0b5774ea443a 100644 --- a/xpfe/components/prefwindow/resources/content/pref-fonts.xul +++ b/xpfe/components/prefwindow/resources/content/pref-fonts.xul @@ -25,11 +25,11 @@ - @@ -40,10 +40,11 @@ - - &displayFonts; - - + + <html:div>&displayFonts;</html:div> + + + &fontsFor.select; @@ -136,10 +137,19 @@ - + + + - - &header2; + + <text value="&header2;"/> + + + + &useDocFontDynamic; + + @@ -154,7 +164,7 @@ &useDefaultFont; - + diff --git a/xpfe/components/prefwindow/resources/content/pref-mousewheel.xul b/xpfe/components/prefwindow/resources/content/pref-mousewheel.xul index 19aa4f3c87b5..1ca6476f6c84 100644 --- a/xpfe/components/prefwindow/resources/content/pref-mousewheel.xul +++ b/xpfe/components/prefwindow/resources/content/pref-mousewheel.xul @@ -25,6 +25,7 @@ + %platformDTD; @@ -37,7 +38,7 @@ class="dialog" onload="if (parent.handle) parent.handle.onpageload('pref-mousewheel'); else parent.queuedTag='pref-mousewheel';" align="vertical" title="&title.label;" - debug="false"> + > @@ -47,79 +48,72 @@ - - - &mouseWheelPanel.label; - + + + + &usingJustTheWheel.label; &usingWheelAndAlt.label; &usingWheelAndCtrl.label; &usingWheelAndShft.label; - + - - - - + + + - + + &scroll.label; - &scroll.label; - - - + + + &scrollLines.label; - - &useSystemDefault.label; - + - + - - - - + + &scrollPgUpPgDn.label; - - + + + - + &history.label; - &history.label; - - - + + &scroll.label; - &scroll.label; - - - + + + &scrollLines.label; - + @@ -127,113 +121,93 @@ &useSystemDefault.label; - + - + &scrollPgUpPgDn.label; - &scrollPgUpPgDn.label; - - - - &history.label; - - + - + + &scroll.label; - &scroll.label; - - - + + + &scrollLines.label; - + &useSystemDefault.label; - &useSystemDefault.label; - - + - + &scrollPgUpPgDn.label; - &scrollPgUpPgDn.label; - - - + &history.label; - &history.label; - - - + - - &scroll.label; - - - + &scroll.label; + + + + &scrollLines.label; - - - &useSystemDefault.label; - + &useSystemDefault.label; + - + - - - &scrollPgUpPgDn.label; - - + &scrollPgUpPgDn.label; + + + - - - &history.label; - - + &history.label; + + - - - + + diff --git a/xpfe/components/prefwindow/resources/content/pref-navigator.xul b/xpfe/components/prefwindow/resources/content/pref-navigator.xul index f1d70cb8b62a..6203eaed7ff4 100644 --- a/xpfe/components/prefwindow/resources/content/pref-navigator.xul +++ b/xpfe/components/prefwindow/resources/content/pref-navigator.xul @@ -25,88 +25,88 @@ - - + - - &navRadio; - + + <text value="&navRadio;"/> + &blankRadio; - + &header2.label; - + &lastPageRadio; - + - - &header2.label; - - &clickRadio; - + + <text value="&header2.label;"/> + + &clickRadio; + &location; - - - - + + + - + - - &header3.label; - + + <text value="&header3.label;"/> + &historyPages; - + &pagesHis; &daysRadio; - + - + - - &header4.label; - + + <html:div>&header4.label;</html:div> + &clearBar; - - + + - + diff --git a/xpfe/components/prefwindow/resources/content/pref-proxies.xul b/xpfe/components/prefwindow/resources/content/pref-proxies.xul index 2abe01a1a6c2..4e6e5a4f7a6e 100644 --- a/xpfe/components/prefwindow/resources/content/pref-proxies.xul +++ b/xpfe/components/prefwindow/resources/content/pref-proxies.xul @@ -40,32 +40,35 @@ - - + + &networkHeader.label; + - &directTypeRadio.label; + + - + - &manualTypeRadio.label; - + + + - - + + &ftp.label; @@ -133,14 +136,13 @@ --> - - &autoTypeRadio.label; - + + &configAutoconfigText.label; @@ -150,7 +152,7 @@ pref="true" preftype="string" prefstring="network.proxy.autoconfig_url"/> - + diff --git a/xpfe/components/prefwindow/resources/content/pref-search.xul b/xpfe/components/prefwindow/resources/content/pref-search.xul index 73709f942a53..084c9a956e7d 100755 --- a/xpfe/components/prefwindow/resources/content/pref-search.xul +++ b/xpfe/components/prefwindow/resources/content/pref-search.xul @@ -24,26 +24,26 @@ - + orient="vertical"> - + - - - &legendHeader; + + + <text value="&legendHeader;"/> - + @@ -67,27 +67,27 @@ - + - - + + - - &searchResults.label; - + + <text value="&searchResults.label;"/> + &openSidebarSearchPanel.label; - + diff --git a/xpfe/components/prefwindow/resources/content/pref-smart_browsing.xul b/xpfe/components/prefwindow/resources/content/pref-smart_browsing.xul index 5c05472679e2..e7b839ecd917 100644 --- a/xpfe/components/prefwindow/resources/content/pref-smart_browsing.xul +++ b/xpfe/components/prefwindow/resources/content/pref-smart_browsing.xul @@ -24,10 +24,10 @@ - @@ -37,10 +37,9 @@ - - - &lHeader; - + + <text value="&lHeader;"/> + @@ -70,26 +69,24 @@ --> - + &doNotDecp.label; - - + - - + - - - &internetKeywordsHeader.label; - + + <text value="&internetKeywordsHeader.label;"/> + &enableKeyCheck.label; - - + + diff --git a/xpfe/components/prefwindow/resources/content/pref-wallet.xul b/xpfe/components/prefwindow/resources/content/pref-wallet.xul index fb8f7e61c7c9..2f9156289e78 100644 --- a/xpfe/components/prefwindow/resources/content/pref-wallet.xul +++ b/xpfe/components/prefwindow/resources/content/pref-wallet.xul @@ -23,7 +23,7 @@ - - - &walletHeader; - &walletDetails; - - + + <text value="&walletHeader;"/> + &walletDetails; + + + &server.label; - - - - + + + + + - + - - &signonHeader; - &signonDetails; - - + + <text value="&signonHeader;"/> + &signonDetails; + + - - + + diff --git a/xpfe/components/prefwindow/resources/locale/en-US/pref-debug.dtd b/xpfe/components/prefwindow/resources/locale/en-US/pref-debug.dtd index ee6d8f7480fa..657d30ac919c 100644 --- a/xpfe/components/prefwindow/resources/locale/en-US/pref-debug.dtd +++ b/xpfe/components/prefwindow/resources/locale/en-US/pref-debug.dtd @@ -10,6 +10,7 @@ + diff --git a/xpfe/components/prefwindow/resources/skin/pref.css b/xpfe/components/prefwindow/resources/skin/pref.css index 597b76013fe8..e648f6c70f13 100644 --- a/xpfe/components/prefwindow/resources/skin/pref.css +++ b/xpfe/components/prefwindow/resources/skin/pref.css @@ -80,6 +80,18 @@ select.font { padding-right: 15px; } +.vspace-both { + padding-top: 7px; + padding-bottom: 7px; +} + +spring.vgap { + height: 12px; +} + +spring.hgap { + width: 12px; +} /* obsolete styles - will be removed soon */ @@ -109,4 +121,4 @@ titledbutton.up { } titledbutton.down { list-style-image: url("chrome://global/skin/scroll-down.gif"); -} \ No newline at end of file +} diff --git a/xpfe/global/resources/skin/global.css b/xpfe/global/resources/skin/global.css index c7eb5f7f5ea4..9b5ec8048bf3 100644 --- a/xpfe/global/resources/skin/global.css +++ b/xpfe/global/resources/skin/global.css @@ -43,7 +43,7 @@ window.dialog { /******** Box *********/ -/* Conditional debug */ +/* Conditional debug *[debug="true"]:-moz-horizontal-box-debug { border: 2px solid blue; @@ -77,24 +77,30 @@ window.dialog { margin: 2px; } +*/ + /* comment this in to make all boxes show their debug info automatically. Otherwise use debug="true" - to show it and use the rules above. + to show it and use the rules above. */ -*:-moz-horizontal-box-debug { +:-moz-horizontal-box-debug { border: 2px solid blue; border-top-width: 10px; padding: 2px; + margin: 2px; color: white; } -*:-moz-vertical-box-debug { +:-moz-vertical-box-debug { border: 2px solid red; border-left-width: 10px; padding: 2px; + margin: 2px; color: white; } -*/ + + + /******* Scrollbar *******/ @@ -607,6 +613,39 @@ progressmeter[mode="undetermined"] background-image: url(chrome://global/skin/progressmeter-busy.gif); } +/********* TitledBox **********/ + +titledbox +{ + display: block; + border: 2px groove white; + padding: 5px; + margin: 2px; +} + +title +{ + display: block; + font-weight: bold; +} + +title > * +{ + margin-left: 5px; + margin-right: 5px; +} + +title > html|* +{ + margin-left: 5px; + margin-right: 5px; +} + +:titledbox-content { + display: block; + padding: inherit; +} + /********* XP Menus ***********/ menubar { diff --git a/xpfe/global/resources/skin/xul.css b/xpfe/global/resources/skin/xul.css index cb1ddd65cff1..52f756c1dae8 100644 --- a/xpfe/global/resources/skin/xul.css +++ b/xpfe/global/resources/skin/xul.css @@ -92,6 +92,18 @@ progressmeter { display: inline; } +/****** TitledBox ******/ + +titledbox +{ + display: block; +} + +title +{ + display: block; +} + /********* XP Menus ***********/ menubar[collapsed="true"] {