From 58cda7a8d08ec42b84ac428ea24c238ec592ce44 Mon Sep 17 00:00:00 2001 From: "hyatt%netscape.com" Date: Tue, 29 Jun 1999 20:20:40 +0000 Subject: [PATCH] Turning on the lazy mode in the tree widget. It is now the default. Let the bug filing begin. :( --- content/shared/public/nsXULAtoms.h | 2 + content/shared/src/nsXULAtoms.cpp | 6 + layout/base/nsCSSFrameConstructor.cpp | 43 ++-- layout/base/nsCSSFrameConstructor.h | 3 +- .../html/style/src/nsCSSFrameConstructor.cpp | 43 ++-- layout/html/style/src/nsCSSFrameConstructor.h | 3 +- .../html/table/src/nsTableRowGroupFrame.cpp | 6 +- layout/html/table/src/nsTableRowGroupFrame.h | 8 +- layout/tables/nsTableRowGroupFrame.cpp | 6 +- layout/tables/nsTableRowGroupFrame.h | 8 +- layout/xul/base/src/nsTreeRowGroupFrame.cpp | 243 ++++++++++++++---- layout/xul/base/src/nsTreeRowGroupFrame.h | 16 +- layout/xul/content/src/nsXULAtoms.cpp | 6 + layout/xul/content/src/nsXULAtoms.h | 2 + 14 files changed, 289 insertions(+), 106 deletions(-) diff --git a/content/shared/public/nsXULAtoms.h b/content/shared/public/nsXULAtoms.h index 188cf5578393..32b517c10279 100644 --- a/content/shared/public/nsXULAtoms.h +++ b/content/shared/public/nsXULAtoms.h @@ -67,6 +67,8 @@ public: static nsIAtom* treeallowevents; // Lets events be handled on the cell contents. static nsIAtom* treecol; // A column in the tree view static nsIAtom* treecolgroup; // A column group in the tree view + static nsIAtom* treefoot; // The footer of the tree view + static nsIAtom* treepusher; // A column pusher (left or right) for the tree view static nsIAtom* progressmeter; static nsIAtom* titledbutton; diff --git a/content/shared/src/nsXULAtoms.cpp b/content/shared/src/nsXULAtoms.cpp index eaecd5b3738d..3d7fb4f7ae19 100644 --- a/content/shared/src/nsXULAtoms.cpp +++ b/content/shared/src/nsXULAtoms.cpp @@ -49,6 +49,8 @@ nsIAtom* nsXULAtoms::treeindentation; nsIAtom* nsXULAtoms::treeallowevents; nsIAtom* nsXULAtoms::treecol; nsIAtom* nsXULAtoms::treecolgroup; +nsIAtom* nsXULAtoms::treefoot; +nsIAtom* nsXULAtoms::treepusher; nsIAtom* nsXULAtoms::progressmeter; nsIAtom* nsXULAtoms::titledbutton; @@ -115,6 +117,8 @@ void nsXULAtoms::AddrefAtoms() { treeallowevents = NS_NewAtom("treeallowevents"); treecol = NS_NewAtom("treecol"); treecolgroup = NS_NewAtom("treecolgroup"); + treefoot = NS_NewAtom("treefoot"); + treepusher = NS_NewAtom("treepusher"); progressmeter = NS_NewAtom("progressmeter"); titledbutton = NS_NewAtom("titledbutton"); @@ -171,6 +175,8 @@ void nsXULAtoms::ReleaseAtoms() { NS_RELEASE(treeallowevents); NS_RELEASE(treecol); NS_RELEASE(treecolgroup); + NS_RELEASE(treefoot); + NS_RELEASE(treepusher); NS_RELEASE(progressmeter); NS_RELEASE(mode); diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index a8315af51784..f97b05a745b0 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -1776,6 +1776,10 @@ nsCSSFrameConstructor::TableIsValidCellContent(nsIPresContext* aPresContext, (nsXULAtoms::treerow == tag.get()) || (nsXULAtoms::treecell == tag.get()) || (nsXULAtoms::treeindentation == tag.get()) || + (nsXULAtoms::treecol == tag.get()) || + (nsXULAtoms::treecolgroup == tag.get()) || + (nsXULAtoms::treefoot == tag.get()) || + (nsXULAtoms::treepusher == tag.get()) || (nsXULAtoms::toolbox == tag.get()) || (nsXULAtoms::toolbar == tag.get()) || (nsXULAtoms::deck == tag.get()) || @@ -2844,6 +2848,12 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext, { rv = NS_NewTreeIndentationFrame(&newFrame); } + else if (aTag == nsXULAtoms::treepusher) + { + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewTitledButtonFrame(&newFrame); + } // End of TREE CONSTRUCTION code here (there's more later on in the function) // TOOLBAR CONSTRUCTION @@ -3009,35 +3019,17 @@ nsCSSFrameConstructor::CreateAnonymousXULContent(nsIPresContext* aPresContext, nsCOMPtr element = do_QueryInterface(grandPappy); nsString mode; element->GetAttribute("mode", mode); - if (tag.get() == nsXULAtoms::tree && mode == "lazy") { - // Create an anonymous scrollbar node. - nsCOMPtr idocument; - aContent->GetDocument(*getter_AddRefs(idocument)); - - nsCOMPtr document(do_QueryInterface(idocument)); - - nsCOMPtr node; - document->CreateElement("scrollbar",getter_AddRefs(node)); - - nsCOMPtr content = do_QueryInterface(node); - content->SetParent(aContent); - - nsCOMPtr vertical = dont_AddRef(NS_NewAtom("align")); - nsCOMPtr style = dont_AddRef(NS_NewAtom("style")); - - content->SetAttribute(kNameSpaceID_None, vertical, "vertical", PR_FALSE); - - ConstructFrame(aPresContext, aState, content, aParentFrame, PR_FALSE, aChildItems); - - ((nsTreeRowGroupFrame*)aParentFrame)->SetScrollbarFrame(aChildItems.lastChild); + if (tag.get() == nsXULAtoms::tree) { + // We will want to have a scrollbar. ((nsTreeRowGroupFrame*)aParentFrame)->SetFrameConstructor(this); + ((nsTreeRowGroupFrame*)aParentFrame)->SetShouldHaveScrollbar(); } } // if we are creating a scrollbar if (aTag == nsXULAtoms::scrollbar) { - // if we have not children create anonymous ones + // if we have no children create anonymous ones PRInt32 count; aContent->ChildCount(count); @@ -6000,7 +5992,8 @@ nsCSSFrameConstructor::CreateTreeWidgetContent(nsIPresContext* aPresContext, nsIFrame* aPrevFrame, nsIContent* aChild, nsIFrame** aNewFrame, - PRBool aIsAppend) + PRBool aIsAppend, + PRBool aIsScrollbar) { nsCOMPtr shell; aPresContext->GetShell(getter_AddRefs(shell)); @@ -6020,7 +6013,9 @@ nsCSSFrameConstructor::CreateTreeWidgetContent(nsIPresContext* aPresContext, if (NS_SUCCEEDED(rv) && (nsnull != newFrame)) { // Notify the parent frame - if (aIsAppend) + if (aIsScrollbar) + ((nsTreeRowGroupFrame*)aParentFrame)->SetScrollbarFrame(newFrame); + else if (aIsAppend) rv = ((nsTreeRowGroupFrame*)aParentFrame)->TreeAppendFrames(newFrame); else rv = ((nsTreeRowGroupFrame*)aParentFrame)->TreeInsertFrames(aPrevFrame, newFrame); diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index ae4624ca4529..04f3d004cce4 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -117,7 +117,8 @@ public: nsIFrame* aPrevFrame, nsIContent* aChild, nsIFrame** aResult, - PRBool aIsAppend); + PRBool aIsAppend, + PRBool aIsScrollbar); protected: diff --git a/layout/html/style/src/nsCSSFrameConstructor.cpp b/layout/html/style/src/nsCSSFrameConstructor.cpp index a8315af51784..f97b05a745b0 100644 --- a/layout/html/style/src/nsCSSFrameConstructor.cpp +++ b/layout/html/style/src/nsCSSFrameConstructor.cpp @@ -1776,6 +1776,10 @@ nsCSSFrameConstructor::TableIsValidCellContent(nsIPresContext* aPresContext, (nsXULAtoms::treerow == tag.get()) || (nsXULAtoms::treecell == tag.get()) || (nsXULAtoms::treeindentation == tag.get()) || + (nsXULAtoms::treecol == tag.get()) || + (nsXULAtoms::treecolgroup == tag.get()) || + (nsXULAtoms::treefoot == tag.get()) || + (nsXULAtoms::treepusher == tag.get()) || (nsXULAtoms::toolbox == tag.get()) || (nsXULAtoms::toolbar == tag.get()) || (nsXULAtoms::deck == tag.get()) || @@ -2844,6 +2848,12 @@ nsCSSFrameConstructor::ConstructXULFrame(nsIPresContext* aPresContext, { rv = NS_NewTreeIndentationFrame(&newFrame); } + else if (aTag == nsXULAtoms::treepusher) + { + processChildren = PR_TRUE; + isReplaced = PR_TRUE; + rv = NS_NewTitledButtonFrame(&newFrame); + } // End of TREE CONSTRUCTION code here (there's more later on in the function) // TOOLBAR CONSTRUCTION @@ -3009,35 +3019,17 @@ nsCSSFrameConstructor::CreateAnonymousXULContent(nsIPresContext* aPresContext, nsCOMPtr element = do_QueryInterface(grandPappy); nsString mode; element->GetAttribute("mode", mode); - if (tag.get() == nsXULAtoms::tree && mode == "lazy") { - // Create an anonymous scrollbar node. - nsCOMPtr idocument; - aContent->GetDocument(*getter_AddRefs(idocument)); - - nsCOMPtr document(do_QueryInterface(idocument)); - - nsCOMPtr node; - document->CreateElement("scrollbar",getter_AddRefs(node)); - - nsCOMPtr content = do_QueryInterface(node); - content->SetParent(aContent); - - nsCOMPtr vertical = dont_AddRef(NS_NewAtom("align")); - nsCOMPtr style = dont_AddRef(NS_NewAtom("style")); - - content->SetAttribute(kNameSpaceID_None, vertical, "vertical", PR_FALSE); - - ConstructFrame(aPresContext, aState, content, aParentFrame, PR_FALSE, aChildItems); - - ((nsTreeRowGroupFrame*)aParentFrame)->SetScrollbarFrame(aChildItems.lastChild); + if (tag.get() == nsXULAtoms::tree) { + // We will want to have a scrollbar. ((nsTreeRowGroupFrame*)aParentFrame)->SetFrameConstructor(this); + ((nsTreeRowGroupFrame*)aParentFrame)->SetShouldHaveScrollbar(); } } // if we are creating a scrollbar if (aTag == nsXULAtoms::scrollbar) { - // if we have not children create anonymous ones + // if we have no children create anonymous ones PRInt32 count; aContent->ChildCount(count); @@ -6000,7 +5992,8 @@ nsCSSFrameConstructor::CreateTreeWidgetContent(nsIPresContext* aPresContext, nsIFrame* aPrevFrame, nsIContent* aChild, nsIFrame** aNewFrame, - PRBool aIsAppend) + PRBool aIsAppend, + PRBool aIsScrollbar) { nsCOMPtr shell; aPresContext->GetShell(getter_AddRefs(shell)); @@ -6020,7 +6013,9 @@ nsCSSFrameConstructor::CreateTreeWidgetContent(nsIPresContext* aPresContext, if (NS_SUCCEEDED(rv) && (nsnull != newFrame)) { // Notify the parent frame - if (aIsAppend) + if (aIsScrollbar) + ((nsTreeRowGroupFrame*)aParentFrame)->SetScrollbarFrame(newFrame); + else if (aIsAppend) rv = ((nsTreeRowGroupFrame*)aParentFrame)->TreeAppendFrames(newFrame); else rv = ((nsTreeRowGroupFrame*)aParentFrame)->TreeInsertFrames(aPrevFrame, newFrame); diff --git a/layout/html/style/src/nsCSSFrameConstructor.h b/layout/html/style/src/nsCSSFrameConstructor.h index ae4624ca4529..04f3d004cce4 100644 --- a/layout/html/style/src/nsCSSFrameConstructor.h +++ b/layout/html/style/src/nsCSSFrameConstructor.h @@ -117,7 +117,8 @@ public: nsIFrame* aPrevFrame, nsIContent* aChild, nsIFrame** aResult, - PRBool aIsAppend); + PRBool aIsAppend, + PRBool aIsScrollbar); protected: diff --git a/layout/html/table/src/nsTableRowGroupFrame.cpp b/layout/html/table/src/nsTableRowGroupFrame.cpp index 9ca2acc8b70a..37b0a829420f 100644 --- a/layout/html/table/src/nsTableRowGroupFrame.cpp +++ b/layout/html/table/src/nsTableRowGroupFrame.cpp @@ -395,7 +395,7 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ? &kidMaxElementSize : nsnull; nsresult rv = NS_OK; - if (!ContinueReflow(aReflowState.y, aReflowState.availSize.height)) + if (!ContinueReflow(aPresContext, aReflowState.y, aReflowState.availSize.height)) return rv; nsIFrame* kidFrame; @@ -494,13 +494,15 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC if (PR_FALSE==aDoSiblings) break; - if (!ContinueReflow(aReflowState.y, aReflowState.availSize.height)) + if (!ContinueReflow(aPresContext, aReflowState.y, aReflowState.availSize.height)) break; // Get the next child GetNextFrameForReflow(aPresContext, kidFrame, &kidFrame); } + // Call our post-row reflow hook + ReflowAfterRowLayout(aPresContext, aDesiredSize, aReflowState, aStatus, aReason); return rv; } diff --git a/layout/html/table/src/nsTableRowGroupFrame.h b/layout/html/table/src/nsTableRowGroupFrame.h index 0f53c7cd86da..6328ee927c16 100644 --- a/layout/html/table/src/nsTableRowGroupFrame.h +++ b/layout/html/table/src/nsTableRowGroupFrame.h @@ -174,7 +174,7 @@ public: virtual PRBool RowGroupReceivesExcessSpace() { return PR_TRUE; } - virtual PRBool ContinueReflow(nscoord y, nscoord height) { return PR_TRUE; } + virtual PRBool ContinueReflow(nsIPresContext& aPresContext, nscoord y, nscoord height) { return PR_TRUE; } protected: @@ -295,6 +295,12 @@ protected: nsReflowStatus& aStatus, nsReflowReason aReason) { return NS_OK; }; + NS_IMETHOD ReflowAfterRowLayout(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + RowGroupReflowState& aReflowState, + nsReflowStatus& aStatus, + nsReflowReason aReason) { return NS_OK; }; + virtual nsIFrame* GetFirstFrameForReflow(nsIPresContext& aPresContext) { return mFrames.FirstChild(); }; virtual void GetNextFrameForReflow(nsIPresContext& aPresContext, nsIFrame* aFrame, nsIFrame** aResult) { aFrame->GetNextSibling(aResult); }; void GetNextRowSibling(nsIFrame** aRowFrame); diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 9ca2acc8b70a..37b0a829420f 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -395,7 +395,7 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ? &kidMaxElementSize : nsnull; nsresult rv = NS_OK; - if (!ContinueReflow(aReflowState.y, aReflowState.availSize.height)) + if (!ContinueReflow(aPresContext, aReflowState.y, aReflowState.availSize.height)) return rv; nsIFrame* kidFrame; @@ -494,13 +494,15 @@ NS_METHOD nsTableRowGroupFrame::ReflowMappedChildren(nsIPresContext& aPresC if (PR_FALSE==aDoSiblings) break; - if (!ContinueReflow(aReflowState.y, aReflowState.availSize.height)) + if (!ContinueReflow(aPresContext, aReflowState.y, aReflowState.availSize.height)) break; // Get the next child GetNextFrameForReflow(aPresContext, kidFrame, &kidFrame); } + // Call our post-row reflow hook + ReflowAfterRowLayout(aPresContext, aDesiredSize, aReflowState, aStatus, aReason); return rv; } diff --git a/layout/tables/nsTableRowGroupFrame.h b/layout/tables/nsTableRowGroupFrame.h index 0f53c7cd86da..6328ee927c16 100644 --- a/layout/tables/nsTableRowGroupFrame.h +++ b/layout/tables/nsTableRowGroupFrame.h @@ -174,7 +174,7 @@ public: virtual PRBool RowGroupReceivesExcessSpace() { return PR_TRUE; } - virtual PRBool ContinueReflow(nscoord y, nscoord height) { return PR_TRUE; } + virtual PRBool ContinueReflow(nsIPresContext& aPresContext, nscoord y, nscoord height) { return PR_TRUE; } protected: @@ -295,6 +295,12 @@ protected: nsReflowStatus& aStatus, nsReflowReason aReason) { return NS_OK; }; + NS_IMETHOD ReflowAfterRowLayout(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + RowGroupReflowState& aReflowState, + nsReflowStatus& aStatus, + nsReflowReason aReason) { return NS_OK; }; + virtual nsIFrame* GetFirstFrameForReflow(nsIPresContext& aPresContext) { return mFrames.FirstChild(); }; virtual void GetNextFrameForReflow(nsIPresContext& aPresContext, nsIFrame* aFrame, nsIFrame** aResult) { aFrame->GetNextSibling(aResult); }; void GetNextRowSibling(nsIFrame** aRowFrame); diff --git a/layout/xul/base/src/nsTreeRowGroupFrame.cpp b/layout/xul/base/src/nsTreeRowGroupFrame.cpp index f78dff9fb3b5..091f029af721 100644 --- a/layout/xul/base/src/nsTreeRowGroupFrame.cpp +++ b/layout/xul/base/src/nsTreeRowGroupFrame.cpp @@ -37,6 +37,8 @@ #include "nsSliderFrame.h" #include "nsIDOMElement.h" #include "nsISupportsArray.h" +#include "nsIDocument.h" +#include "nsIDOMDocument.h" // // NS_NewTreeFrame @@ -64,7 +66,7 @@ NS_NewTreeRowGroupFrame (nsIFrame** aNewFrame) nsTreeRowGroupFrame::nsTreeRowGroupFrame() :nsTableRowGroupFrame(), mScrollbar(nsnull), mFrameConstructor(nsnull), mTopFrame(nsnull), mBottomFrame(nsnull), mIsLazy(PR_FALSE), mIsFull(PR_FALSE), - mContentChain(nsnull), mLinkupFrame(nsnull) + mContentChain(nsnull), mLinkupFrame(nsnull), mShouldHaveScrollbar(PR_FALSE) { } // Destructor @@ -120,7 +122,7 @@ void nsTreeRowGroupFrame::DestroyRows(nsIPresContext& aPresContext, PRInt32& row ((nsTreeRowGroupFrame*)childFrame)->DestroyRows(aPresContext, rowsToLose); return; } - else rowsToLose = 0; + else rowsToLose -= rowGroupCount; } else if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay) { @@ -153,7 +155,7 @@ void nsTreeRowGroupFrame::ReverseDestroyRows(nsIPresContext& aPresContext, PRInt ((nsTreeRowGroupFrame*)childFrame)->ReverseDestroyRows(aPresContext, rowsToLose); return; } - else rowsToLose = 0; + else rowsToLose -= rowGroupCount; } else if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay) { @@ -356,13 +358,57 @@ nsTreeRowGroupFrame::FindPreviousRowContent(PRInt32& aDelta, nsIContent* aUpward // Bail. There's nothing else we can do. } +void +nsTreeRowGroupFrame::GetVisibleRowCount(PRInt32& aCount, nsIContent* aParent) +{ + PRInt32 childCount; + aParent->ChildCount(childCount); + + for (PRInt32 i = 0; i < childCount; i++) { + nsCOMPtr childContent; + aParent->ChildAt(i, *getter_AddRefs(childContent)); + nsCOMPtr tag; + childContent->GetTag(*getter_AddRefs(tag)); + if (tag.get() == nsXULAtoms::treerow) { + aCount++; + } + else if (tag.get() == nsXULAtoms::treeitem) { + // Descend into this row group and try to find the next row. + GetVisibleRowCount(aCount, childContent); + + // If it's open, descend into its treechildren. + nsCOMPtr openAtom = dont_AddRef(NS_NewAtom("open")); + nsString isOpen; + childContent->GetAttribute(kNameSpaceID_None, openAtom, isOpen); + if (isOpen == "true") { + // Find the node. + PRInt32 childContentCount; + nsCOMPtr grandChild; + childContent->ChildCount(childContentCount); + + PRInt32 j; + for (j = childContentCount-1; j >= 0; j--) { + + childContent->ChildAt(j, *getter_AddRefs(grandChild)); + nsCOMPtr grandChildTag; + grandChild->GetTag(*getter_AddRefs(grandChildTag)); + if (grandChildTag.get() == nsXULAtoms::treechildren) + break; + } + if (j >= 0 && grandChild) + GetVisibleRowCount(aCount, grandChild); + } + } + } +} + NS_IMETHODIMP nsTreeRowGroupFrame::PositionChanged(nsIPresContext& aPresContext, PRInt32 aOldIndex, PRInt32 aNewIndex) { if (aOldIndex == aNewIndex) return NS_OK; - printf("The position changed!\n"); + //printf("The position changed! The new index is: %d\n", aNewIndex); if (mContentChain) { NS_ERROR("This is bad!"); @@ -380,6 +426,8 @@ nsTreeRowGroupFrame::PositionChanged(nsIPresContext& aPresContext, PRInt32 aOldI // Figure out how many rows we need to lose (if we moved down) or gain (if we moved up). PRInt32 delta = aNewIndex > aOldIndex ? aNewIndex - aOldIndex : aOldIndex - aNewIndex; + //printf("The delta is: %d\n", delta); + // Get our presentation context. if (delta < rowCount) { PRInt32 loseRows = delta; @@ -409,7 +457,8 @@ nsTreeRowGroupFrame::PositionChanged(nsIPresContext& aPresContext, PRInt32 aOldI mFrames.DeleteFrames(aPresContext); nsCOMPtr topRowContent; FindRowContentAtIndex(aNewIndex, mContent, getter_AddRefs(topRowContent)); - ConstructContentChain(topRowContent); + if (topRowContent) + ConstructContentChain(topRowContent); } // Invalidate the cell map and column cache. @@ -427,28 +476,42 @@ nsTreeRowGroupFrame::PositionChanged(nsIPresContext& aPresContext, PRInt32 aOldI NS_IMETHODIMP nsTreeRowGroupFrame::PagedUpDown() { - printf("Hey! You paged up and down!\n"); + // Set the scrollbar's pageincrement + if (mScrollbar) { + PRInt32 rowGroupCount; + GetRowCount(rowGroupCount); + + nsCOMPtr scrollbarContent; + mScrollbar->GetContent(getter_AddRefs(scrollbarContent)); + + rowGroupCount--; + char ch[100]; + sprintf(ch,"%d", rowGroupCount); + + scrollbarContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::pageincrement, nsString(ch), PR_FALSE); + } + return NS_OK; } void nsTreeRowGroupFrame::SetScrollbarFrame(nsIFrame* aFrame) { - mIsLazy = PR_TRUE; mScrollbar = aFrame; - nsCOMPtr sliderAtom = dont_AddRef(NS_NewAtom("slider")); - nsCOMPtr incrementAtom = dont_AddRef(NS_NewAtom("increment")); - nsCOMPtr pageIncrementAtom = dont_AddRef(NS_NewAtom("pageincrement")); - + // Place it in its own list. + mScrollbarList.AppendFrames(this, nsFrameList(mScrollbar)); + nsCOMPtr scrollbarContent; aFrame->GetContent(getter_AddRefs(scrollbarContent)); - scrollbarContent->SetAttribute(kNameSpaceID_None, incrementAtom, "1", PR_FALSE); - scrollbarContent->SetAttribute(kNameSpaceID_None, pageIncrementAtom, "1", PR_FALSE); + scrollbarContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::curpos, "0", PR_FALSE); + scrollbarContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::increment, "1", PR_FALSE); + scrollbarContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::pageincrement, "1", PR_FALSE); + scrollbarContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::maxpos, "5000", PR_FALSE); nsIFrame* result; - nsScrollbarButtonFrame::GetChildWithTag(sliderAtom, aFrame, result); + nsScrollbarButtonFrame::GetChildWithTag(nsXULAtoms::slider, aFrame, result); ((nsSliderFrame*)result)->SetScrollbarListener(this); } @@ -555,7 +618,28 @@ nsTreeRowGroupFrame::ReflowBeforeRowLayout(nsIPresContext& aPresContext, { nsresult rv = NS_OK; // Reflow a scrollbar if we have one. - if (mScrollbar && (aReflowState.availSize.height != NS_UNCONSTRAINEDSIZE)) { + if (mShouldHaveScrollbar && (aReflowState.availSize.height != NS_UNCONSTRAINEDSIZE)) { + // Ensure the scrollbar has been created. + if (!mScrollbar) + CreateScrollbar(aPresContext); + + PRInt32 rowCount = 0; + GetVisibleRowCount(rowCount, mContent); // XXX This sucks! Needs to be cheap! + + // Set the maxpos of the scrollbar. + nsCOMPtr scrollbarContent; + mScrollbar->GetContent(getter_AddRefs(scrollbarContent)); + + rowCount--; + if (rowCount < 0) + rowCount = 0; + + char ch[100]; + sprintf(ch,"%d", rowCount); + + // Make sure our position is accurate. + scrollbarContent->SetAttribute(kNameSpaceID_None, nsXULAtoms::maxpos, nsString(ch), PR_FALSE); + // We must be constrained, or a scrollbar makes no sense. nsSize kidMaxElementSize; nsSize* pKidMaxElementSize = (nsnull != aDesiredSize.maxElementSize) ? &kidMaxElementSize : nsnull; @@ -593,6 +677,30 @@ nsTreeRowGroupFrame::ReflowBeforeRowLayout(nsIPresContext& aPresContext, return rv; } +NS_IMETHODIMP +nsTreeRowGroupFrame::ReflowAfterRowLayout(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + RowGroupReflowState& aReflowState, + nsReflowStatus& aStatus, + nsReflowReason aReason) +{ + nsresult rv = NS_OK; + if (mScrollbar) { + nsCOMPtr scrollbarContent; + mScrollbar->GetContent(getter_AddRefs(scrollbarContent)); + nsString value; + nsIAtom* hiddenAtom = NS_NewAtom("hidden"); + scrollbarContent->GetAttribute(kNameSpaceID_None, nsXULAtoms::curpos, value); + if (value == "0" && !mIsFull) { + // Nuke the scrollbar. + mScrollbarList.DeleteFrames(aPresContext); + mScrollbar = nsnull; + } + } + return rv; +} + + void nsTreeRowGroupFrame::LocateFrame(nsIFrame* aStartFrame, nsIFrame** aResult) { if (aStartFrame == nsnull) @@ -600,15 +708,6 @@ void nsTreeRowGroupFrame::LocateFrame(nsIFrame* aStartFrame, nsIFrame** aResult) *aResult = mFrames.FirstChild(); } else aStartFrame->GetNextSibling(aResult); - - if (mScrollbar && (*aResult == mScrollbar)) { - // Get this out of our flow. - mScrollbar->GetNextSibling(aResult); - mFrames.RemoveFrame(mScrollbar); - - // Put it into a special list of our own. - mScrollbarList.AppendFrame(this, mScrollbar); - } } nsIFrame* @@ -659,30 +758,35 @@ nsTreeRowGroupFrame::GetFirstFrameForReflow(nsIPresContext& aPresContext) mBottomFrame = mTopFrame; nsCOMPtr startContent; - if (mTopFrame) { - if (!mContentChain) - return mTopFrame; - - // We have a content chain. If the top frame is the same as our content - // chain, we can go ahead and destroy our content chain and return the - // top frame. - nsCOMPtr topContent; - mTopFrame->GetContent(getter_AddRefs(topContent)); + if (mContentChain) { nsCOMPtr supports; mContentChain->GetElementAt(0, getter_AddRefs(supports)); nsCOMPtr chainContent = do_QueryInterface(supports); - if (chainContent.get() == topContent.get()) { - // The two content nodes are the same. Our content chain has - // been synched up, and we can now remove our element and - // pass the content chain inwards. - InitSubContentChain((nsTreeRowGroupFrame*)mTopFrame); - } - else mLinkupFrame = mTopFrame; // We have some frames that we'll eventually catch up with. - // Cache the pointer to the first of these frames, so - // we'll know it when we hit it. - startContent = chainContent; + + if (mTopFrame) { + + // We have a content chain. If the top frame is the same as our content + // chain, we can go ahead and destroy our content chain and return the + // top frame. + nsCOMPtr topContent; + mTopFrame->GetContent(getter_AddRefs(topContent)); + if (chainContent.get() == topContent.get()) { + // The two content nodes are the same. Our content chain has + // been synched up, and we can now remove our element and + // pass the content chain inwards. + InitSubContentChain((nsTreeRowGroupFrame*)mTopFrame); + } + else mLinkupFrame = mTopFrame; // We have some frames that we'll eventually catch up with. + // Cache the pointer to the first of these frames, so + // we'll know it when we hit it. + } } + else if (mTopFrame) { + return mTopFrame; + } + + // We don't have a top frame instantiated. Let's // try to make one. @@ -704,8 +808,8 @@ nsTreeRowGroupFrame::GetFirstFrameForReflow(nsIPresContext& aPresContext) PRBool isAppend = (mLinkupFrame == nsnull); mFrameConstructor->CreateTreeWidgetContent(&aPresContext, this, nsnull, startContent, - &mTopFrame, isAppend); - printf("Created a frame\n"); + &mTopFrame, isAppend, PR_FALSE); + //printf("Created a frame\n"); mBottomFrame = mTopFrame; const nsStyleDisplay *rowDisplay; mTopFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)rowDisplay); @@ -773,8 +877,8 @@ nsTreeRowGroupFrame::GetNextFrameForReflow(nsIPresContext& aPresContext, nsIFram isAppend = PR_FALSE; } mFrameConstructor->CreateTreeWidgetContent(&aPresContext, this, prevFrame, nextContent, - aResult, isAppend); - printf("Created a frame\n"); + aResult, isAppend, PR_FALSE); + //printf("Created a frame\n"); const nsStyleDisplay *rowDisplay; (*aResult)->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)rowDisplay); if (NS_STYLE_DISPLAY_TABLE_ROW==rowDisplay->mDisplay) { @@ -805,12 +909,25 @@ nsTreeRowGroupFrame::TreeAppendFrames(nsIFrame* aFrameList) return NS_OK; } -PRBool nsTreeRowGroupFrame::ContinueReflow(nscoord y, nscoord height) +PRBool nsTreeRowGroupFrame::ContinueReflow(nsIPresContext& aPresContext, nscoord y, nscoord height) { //printf("Y is: %d\n", y); //printf("Height is: %d\n", height); if (height <= 0 && IsLazy()) { mIsFull = PR_TRUE; + nsIFrame* lastChild = GetLastFrame(); + if (lastChild != mBottomFrame) { + // We have some hangers on (probably caused by shrinking the size of the window). + // Nuke them. + nsIFrame* currFrame; + mBottomFrame->GetNextSibling(&currFrame); + while (currFrame) { + nsIFrame* nextFrame; + currFrame->GetNextSibling(&nextFrame); + mFrames.DeleteFrame(aPresContext, currFrame); + currFrame = nextFrame; + } + } return PR_FALSE; } else @@ -862,3 +979,33 @@ void nsTreeRowGroupFrame::InitSubContentChain(nsTreeRowGroupFrame* aRowGroupFram } } +void nsTreeRowGroupFrame::SetShouldHaveScrollbar() +{ + mShouldHaveScrollbar = PR_TRUE; + mIsLazy = PR_TRUE; +} + +void nsTreeRowGroupFrame::CreateScrollbar(nsIPresContext& aPresContext) +{ + if (mShouldHaveScrollbar && !mScrollbar) { + // Create an anonymous scrollbar node. + nsCOMPtr idocument; + mContent->GetDocument(*getter_AddRefs(idocument)); + + nsCOMPtr document(do_QueryInterface(idocument)); + + nsCOMPtr node; + document->CreateElement("scrollbar",getter_AddRefs(node)); + + nsCOMPtr content = do_QueryInterface(node); + content->SetParent(mContent); + + nsCOMPtr align = dont_AddRef(NS_NewAtom("align")); + content->SetAttribute(kNameSpaceID_None, align, "vertical", PR_FALSE); + + nsIFrame* aResult; + mFrameConstructor->CreateTreeWidgetContent(&aPresContext, this, nsnull, content, + &aResult, PR_FALSE, PR_TRUE); + + } +} \ No newline at end of file diff --git a/layout/xul/base/src/nsTreeRowGroupFrame.h b/layout/xul/base/src/nsTreeRowGroupFrame.h index fcd158bd77c1..e50ac47983b6 100644 --- a/layout/xul/base/src/nsTreeRowGroupFrame.h +++ b/layout/xul/base/src/nsTreeRowGroupFrame.h @@ -36,6 +36,9 @@ public: void SetScrollbarFrame(nsIFrame* aFrame); void SetFrameConstructor(nsCSSFrameConstructor* aFrameConstructor) { mFrameConstructor = aFrameConstructor; }; + void SetShouldHaveScrollbar(); + + void CreateScrollbar(nsIPresContext& aPresContext); void MakeLazy() { mIsLazy = PR_TRUE; }; PRBool IsLazy() { return mIsLazy; }; @@ -51,7 +54,7 @@ public: const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer); - PRBool ContinueReflow(nscoord y, nscoord height); + PRBool ContinueReflow(nsIPresContext& aPresContext, nscoord y, nscoord height); PRBool IsFull() { return mIsFull; }; @@ -84,6 +87,12 @@ protected: nsReflowStatus& aStatus, nsReflowReason aReason); + NS_IMETHOD ReflowAfterRowLayout(nsIPresContext& aPresContext, + nsHTMLReflowMetrics& aDesiredSize, + RowGroupReflowState& aReflowState, + nsReflowStatus& aStatus, + nsReflowReason aReason); + virtual nsIFrame* GetFirstFrameForReflow(nsIPresContext& aPresContext); virtual void GetNextFrameForReflow(nsIPresContext& aPresContext, nsIFrame* aFrame, nsIFrame** aResult); @@ -99,6 +108,8 @@ protected: nsIContent** aResult); void GetFirstRowContent(nsIContent** aRowContent); + void GetVisibleRowCount(PRInt32& rowCount, nsIContent* aParent); + NS_IMETHOD DeleteFrame(nsIPresContext& aPresContext); protected: // Data Members @@ -108,9 +119,10 @@ protected: // Data Members PRBool mIsLazy; // Whether or not we're a lazily instantiated beast PRBool mIsFull; // Whether or not we have any more room. - + nsIFrame* mScrollbar; // Our scrollbar. nsFrameList mScrollbarList; // A frame list that holds our scrollbar. + PRBool mShouldHaveScrollbar; // Whether or not we could potentially have a scrollbar. nsISupportsArray* mContentChain; // Our content chain diff --git a/layout/xul/content/src/nsXULAtoms.cpp b/layout/xul/content/src/nsXULAtoms.cpp index eaecd5b3738d..3d7fb4f7ae19 100644 --- a/layout/xul/content/src/nsXULAtoms.cpp +++ b/layout/xul/content/src/nsXULAtoms.cpp @@ -49,6 +49,8 @@ nsIAtom* nsXULAtoms::treeindentation; nsIAtom* nsXULAtoms::treeallowevents; nsIAtom* nsXULAtoms::treecol; nsIAtom* nsXULAtoms::treecolgroup; +nsIAtom* nsXULAtoms::treefoot; +nsIAtom* nsXULAtoms::treepusher; nsIAtom* nsXULAtoms::progressmeter; nsIAtom* nsXULAtoms::titledbutton; @@ -115,6 +117,8 @@ void nsXULAtoms::AddrefAtoms() { treeallowevents = NS_NewAtom("treeallowevents"); treecol = NS_NewAtom("treecol"); treecolgroup = NS_NewAtom("treecolgroup"); + treefoot = NS_NewAtom("treefoot"); + treepusher = NS_NewAtom("treepusher"); progressmeter = NS_NewAtom("progressmeter"); titledbutton = NS_NewAtom("titledbutton"); @@ -171,6 +175,8 @@ void nsXULAtoms::ReleaseAtoms() { NS_RELEASE(treeallowevents); NS_RELEASE(treecol); NS_RELEASE(treecolgroup); + NS_RELEASE(treefoot); + NS_RELEASE(treepusher); NS_RELEASE(progressmeter); NS_RELEASE(mode); diff --git a/layout/xul/content/src/nsXULAtoms.h b/layout/xul/content/src/nsXULAtoms.h index 188cf5578393..32b517c10279 100644 --- a/layout/xul/content/src/nsXULAtoms.h +++ b/layout/xul/content/src/nsXULAtoms.h @@ -67,6 +67,8 @@ public: static nsIAtom* treeallowevents; // Lets events be handled on the cell contents. static nsIAtom* treecol; // A column in the tree view static nsIAtom* treecolgroup; // A column group in the tree view + static nsIAtom* treefoot; // The footer of the tree view + static nsIAtom* treepusher; // A column pusher (left or right) for the tree view static nsIAtom* progressmeter; static nsIAtom* titledbutton;