/* -*- 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): */ #ifndef nsTableOuterFrame_h__ #define nsTableOuterFrame_h__ #include "nscore.h" #include "nsHTMLContainerFrame.h" #include "nsBlockFrame.h" #include "nsITableLayout.h" struct OuterTableReflowState; struct nsStyleTable; class nsTableCaptionFrame : public nsBlockFrame { public: // nsISupports NS_IMETHOD GetFrameType(nsIAtom** aType) const; friend nsresult NS_NewTableCaptionFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame); protected: nsTableCaptionFrame(); virtual ~nsTableCaptionFrame(); }; /* TODO 1. decide if we'll allow subclassing. If so, decide which methods really need to be virtual. */ /** * main frame for an nsTable content object, * the nsTableOuterFrame contains 0 or one caption frame, and a nsTableFrame * psuedo-frame (referred to as the "inner frame'). */ class nsTableOuterFrame : public nsHTMLContainerFrame, public nsITableLayout { public: // nsISupports NS_DECL_ISUPPORTS_INHERITED /** instantiate a new instance of nsTableOuterFrame. * @param aResult the new object is returned in this out-param * * @return NS_OK if the frame was properly allocated, otherwise an error code */ friend nsresult NS_NewTableOuterFrame(nsIPresShell* aPresShell, nsIFrame** aResult); NS_IMETHOD Init(nsIPresContext* aPresContext, nsIContent* aContent, nsIFrame* aParent, nsIStyleContext* aContext, nsIFrame* aPrevInFlow); NS_IMETHOD Destroy(nsIPresContext* aPresContext); NS_IMETHOD AdjustZeroWidth(); /** @see nsIFrame::SetInitialChildList */ NS_IMETHOD SetInitialChildList(nsIPresContext* aPresContext, nsIAtom* aListName, nsIFrame* aChildList); NS_IMETHOD FirstChild(nsIPresContext* aPresContext, nsIAtom* aListName, nsIFrame** aFirstChild) const; NS_IMETHOD GetAdditionalChildListName(PRInt32 aIndex, nsIAtom** aListName) const; NS_IMETHOD AppendFrames(nsIPresContext* aPresContext, nsIPresShell& aPresShell, nsIAtom* aListName, nsIFrame* aFrameList); NS_IMETHOD InsertFrames(nsIPresContext* aPresContext, nsIPresShell& aPresShell, nsIAtom* aListName, nsIFrame* aPrevFrame, nsIFrame* aFrameList); NS_IMETHOD RemoveFrame(nsIPresContext* aPresContext, nsIPresShell& aPresShell, nsIAtom* aListName, nsIFrame* aOldFrame); /** @see nsIFrame::Paint */ NS_IMETHOD Paint(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, const nsRect& aDirtyRect, nsFramePaintLayer aWhichLayer); NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext, const nsPoint& aPoint, nsFramePaintLayer aWhichLayer, nsIFrame** aFrame); /** process a reflow command for the table. * This involves reflowing the caption and the inner table. * @see nsIFrame::Reflow */ NS_IMETHOD Reflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, const nsHTMLReflowState& aReflowState, nsReflowStatus& aStatus); /** * Get the "type" of the frame * * @see nsLayoutAtoms::tableOuterFrame */ NS_IMETHOD GetFrameType(nsIAtom** aType) const; #ifdef DEBUG NS_IMETHOD GetFrameName(nsString& aResult) const; NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const; #endif /** SetSelected needs to be overridden to talk to inner tableframe */ NS_IMETHOD SetSelected(nsIPresContext* aPresContext, nsIDOMRange *aRange, PRBool aSelected, nsSpread aSpread); /** return the min width of the caption. Return 0 if there is no caption. * The return value is only meaningful after the caption has had a pass1 reflow. */ nscoord GetMinCaptionWidth(); /*---------------- nsITableLayout methods ------------------------*/ /** @see nsITableFrame::GetCellDataAt */ NS_IMETHOD GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex, nsIDOMElement* &aCell, //out params PRInt32& aStartRowIndex, PRInt32& aStartColIndex, PRInt32& aRowSpan, PRInt32& aColSpan, PRInt32& aActualRowSpan, PRInt32& aActualColSpan, PRBool& aIsSelected); /** @see nsITableFrame::GetTableSize */ NS_IMETHOD GetTableSize(PRInt32& aRowCount, PRInt32& aColCount); protected: nsTableOuterFrame(); virtual ~nsTableOuterFrame(); /** Always returns 0, since the outer table frame has no border of its own * The inner table frame can answer this question in a meaningful way. * @see nsHTMLContainerFrame::GetSkipSides */ virtual PRIntn GetSkipSides() const; /** return PR_TRUE if the table needs to be reflowed. * the outer table needs to be reflowed if the table content has changed, * or if the table style attributes or parent max height/width have * changed. */ PRBool NeedsReflow(const nsHTMLReflowState& aReflowState); /** overridden here to handle special caption-table relationship * @see nsContainerFrame::VerifyTree */ NS_IMETHOD VerifyTree() const; /** * Remove and delete aChild's next-in-flow(s). Updates the sibling and flow * pointers. * * Updates the child count and content offsets of all containers that are * affected * * Overloaded here because nsContainerFrame makes assumptions about pseudo-frames * that are not true for tables. * * @param aChild child this child's next-in-flow * @return PR_TRUE if successful and PR_FALSE otherwise */ virtual void DeleteChildsNextInFlow(nsIPresContext* aPresContext, nsIFrame* aChild); // begin Incremental Reflow methods /** prepare aReflowState for an incremental reflow */ NS_IMETHOD RecoverState(OuterTableReflowState& aReflowState, nsIFrame* aKidFrame); /** process an incremental reflow command */ NS_IMETHOD IncrementalReflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, OuterTableReflowState& aReflowState, nsReflowStatus& aStatus); /** process an incremental reflow command targeted at a child of this frame. */ NS_IMETHOD IR_TargetIsChild(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, OuterTableReflowState& aReflowState, nsReflowStatus& aStatus, nsIFrame * aNextFrame); /** process an incremental reflow command targeted at the table inner frame. */ NS_IMETHOD IR_TargetIsInnerTableFrame(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, OuterTableReflowState& aReflowState, nsReflowStatus& aStatus); /** process an incremental reflow command targeted at the caption. */ NS_IMETHOD IR_TargetIsCaptionFrame(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, OuterTableReflowState& aReflowState, nsReflowStatus& aStatus); /** process an incremental reflow command targeted at this frame. * many incremental reflows that are targeted at this outer frame * are actually handled by the inner frame. The logic to decide this * is here. */ NS_IMETHOD IR_TargetIsMe(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, OuterTableReflowState& aReflowState, nsReflowStatus& aStatus); /** pass along the incremental reflow command to the inner table. */ NS_IMETHOD IR_InnerTableReflow(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, OuterTableReflowState& aReflowState, nsReflowStatus& aStatus); /** handle incremental reflow notification that a caption was inserted. */ NS_IMETHOD IR_CaptionInserted(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, OuterTableReflowState& aReflowState, nsReflowStatus& aStatus); /** handle incremental reflow notification that we have dirty child frames */ NS_IMETHOD IR_ReflowDirty(nsIPresContext* aPresContext, nsHTMLReflowMetrics& aDesiredSize, OuterTableReflowState& aReflowState, nsReflowStatus& aStatus); /** handle incremental reflow notification that the caption style was changed * such that it is now left|right instead of top|bottom, or vice versa. */ PRBool IR_CaptionChangedAxis(const nsStyleTable* aOldStyle, const nsStyleTable* aNewStyle) const; /** set the size and the location of both the inner table frame and the caption. */ NS_IMETHOD SizeAndPlaceChildren(nsIPresContext* aPresContext, const nsSize& aInnerSize, const nsSize& aCaptionSize, OuterTableReflowState& aReflowState, const nsMargin& aCaptionMargin); // end Incremental Reflow methods // The following function at least lets the tree widget work // inside boxes. It repairs the reflow state after it's been // screwed up by the nsHTMLReflowState code. NS_IMETHOD FixBadReflowState(const nsHTMLReflowState& aParentReflowState, nsHTMLReflowState& aChildReflowState) { return NS_OK; }; private: /** used to keep track of this frame's children */ nsIFrame *mInnerTableFrame; // XXX this is redundant, mFrames holds the same nsIFrame *mCaptionFrame; /** used to track caption max element size */ PRInt32 mMinCaptionWidth; nsSize mMaxElementSize; nscoord mInnerTableMaximumWidth; }; inline nscoord nsTableOuterFrame::GetMinCaptionWidth() { return mMinCaptionWidth; } inline PRIntn nsTableOuterFrame::GetSkipSides() const { return 0; } #endif