michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: #ifndef nsTableColGroupFrame_h__ michael@0: #define nsTableColGroupFrame_h__ michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: #include "nscore.h" michael@0: #include "nsContainerFrame.h" michael@0: #include "nsTableColFrame.h" michael@0: michael@0: class nsTableFrame; michael@0: class nsTableColFrame; michael@0: michael@0: enum nsTableColGroupType { michael@0: eColGroupContent = 0, // there is real col group content associated michael@0: eColGroupAnonymousCol = 1, // the result of a col michael@0: eColGroupAnonymousCell = 2 // the result of a cell alone michael@0: }; michael@0: michael@0: /** michael@0: * nsTableColGroupFrame michael@0: * data structure to maintain information about a single table cell's frame michael@0: * michael@0: * @author sclark michael@0: */ michael@0: class nsTableColGroupFrame : public nsContainerFrame michael@0: { michael@0: public: michael@0: NS_DECL_FRAMEARENA_HELPERS michael@0: michael@0: // default constructor supplied by the compiler michael@0: michael@0: /** instantiate a new instance of nsTableRowFrame. michael@0: * @param aPresShell the pres shell for this frame michael@0: * michael@0: * @return the frame that was created michael@0: */ michael@0: friend nsIFrame* NS_NewTableColGroupFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); michael@0: michael@0: /** Initialize the colgroup frame with a set of children. michael@0: * @see nsIFrame::SetInitialChildList michael@0: */ michael@0: virtual nsresult SetInitialChildList(ChildListID aListID, michael@0: nsFrameList& aChildList) MOZ_OVERRIDE; michael@0: michael@0: /** michael@0: * ColGroups never paint anything, nor receive events. michael@0: */ michael@0: virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, michael@0: const nsRect& aDirtyRect, michael@0: const nsDisplayListSet& aLists) MOZ_OVERRIDE {} michael@0: michael@0: /** A colgroup can be caused by three things: michael@0: * 1) An element with table-column-group display michael@0: * 2) An element with a table-column display without a michael@0: * table-column-group parent michael@0: * 3) Cells that are not in a column (and hence get an anonymous michael@0: * column and colgroup). michael@0: * @return colgroup type michael@0: */ michael@0: nsTableColGroupType GetColType() const; michael@0: michael@0: /** Set the colgroup type based on the creation cause michael@0: * @param aType - the reason why this colgroup is needed michael@0: */ michael@0: void SetColType(nsTableColGroupType aType); michael@0: michael@0: /** Real in this context are colgroups that come from an element michael@0: * with table-column-group display or wrap around columns that michael@0: * come from an element with table-column display. Colgroups michael@0: * that are the result of wrapping cells in an anonymous michael@0: * column and colgroup are not considered real here. michael@0: * @param aTableFrame - the table parent of the colgroups michael@0: * @return the last real colgroup michael@0: */ michael@0: static nsTableColGroupFrame* GetLastRealColGroup(nsTableFrame* aTableFrame); michael@0: michael@0: /** @see nsIFrame::DidSetStyleContext */ michael@0: virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) MOZ_OVERRIDE; michael@0: michael@0: /** @see nsIFrame::AppendFrames, InsertFrames, RemoveFrame michael@0: */ michael@0: virtual nsresult AppendFrames(ChildListID aListID, michael@0: nsFrameList& aFrameList) MOZ_OVERRIDE; michael@0: virtual nsresult InsertFrames(ChildListID aListID, michael@0: nsIFrame* aPrevFrame, michael@0: nsFrameList& aFrameList) MOZ_OVERRIDE; michael@0: virtual nsresult RemoveFrame(ChildListID aListID, michael@0: nsIFrame* aOldFrame) MOZ_OVERRIDE; michael@0: michael@0: /** remove the column aChild from the column group, if requested renumber michael@0: * the subsequent columns in this column group and all following column michael@0: * groups. see also ResetColIndices for this michael@0: * @param aChild - the column frame that needs to be removed michael@0: * @param aResetSubsequentColIndices - if true the columns that follow michael@0: * after aChild will be reenumerated michael@0: */ michael@0: void RemoveChild(nsTableColFrame& aChild, michael@0: bool aResetSubsequentColIndices); michael@0: michael@0: /** reflow of a column group is a trivial matter of reflowing michael@0: * the col group's children (columns), and setting this frame michael@0: * to 0-size. Since tables are row-centric, column group frames michael@0: * don't play directly in the rendering game. They do however michael@0: * maintain important state that effects table and cell layout. michael@0: */ michael@0: virtual nsresult Reflow(nsPresContext* aPresContext, michael@0: nsHTMLReflowMetrics& aDesiredSize, michael@0: const nsHTMLReflowState& aReflowState, michael@0: nsReflowStatus& aStatus) MOZ_OVERRIDE; michael@0: michael@0: /** michael@0: * Get the "type" of the frame michael@0: * michael@0: * @see nsGkAtoms::tableColGroupFrame michael@0: */ michael@0: virtual nsIAtom* GetType() const MOZ_OVERRIDE; michael@0: michael@0: /** Add column frames to the table storages: colframe cache and cellmap michael@0: * this doesn't change the mFrames of the colgroup frame. michael@0: * @param aFirstColIndex - the index at which aFirstFrame should be inserted michael@0: * into the colframe cache. michael@0: * @param aResetSubsequentColIndices - the indices of the col frames michael@0: * after the insertion might need michael@0: * an update michael@0: * @param aCols - an iterator that can be used to iterate over the col michael@0: * frames to be added. Once this is done, the frames on the michael@0: * sbling chain of its .get() at that point will still need michael@0: * their col indices updated. michael@0: * @result - if there is no table frame or the table frame is not michael@0: * the first in flow it will return an error michael@0: */ michael@0: nsresult AddColsToTable(int32_t aFirstColIndex, michael@0: bool aResetSubsequentColIndices, michael@0: const nsFrameList::Slice& aCols); michael@0: michael@0: #ifdef DEBUG_FRAME_DUMP michael@0: virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE; michael@0: void Dump(int32_t aIndent); michael@0: #endif michael@0: michael@0: /** returns the number of columns represented by this group. michael@0: * if there are col children, count them (taking into account the span of each) michael@0: * else, check my own span attribute. michael@0: */ michael@0: virtual int32_t GetColCount() const; michael@0: michael@0: /** first column on the child list */ michael@0: nsTableColFrame * GetFirstColumn(); michael@0: /** next sibling to aChildFrame that is a column frame, first column frame michael@0: * in the column group if aChildFrame is null michael@0: */ michael@0: nsTableColFrame * GetNextColumn(nsIFrame *aChildFrame); michael@0: michael@0: /** @return - the position of the first column in this colgroup in the table michael@0: * colframe cache. michael@0: */ michael@0: int32_t GetStartColumnIndex(); michael@0: michael@0: /** set the position of the first column in this colgroup in the table michael@0: * colframe cache. michael@0: */ michael@0: void SetStartColumnIndex(int32_t aIndex); michael@0: michael@0: /** helper method to get the span attribute for this colgroup */ michael@0: int32_t GetSpan(); michael@0: michael@0: /** provide access to the mFrames list michael@0: */ michael@0: nsFrameList& GetWritableChildList(); michael@0: michael@0: /** set the column index for all frames starting at aStartColFrame, it michael@0: * will also reset the column indices in all subsequent colgroups michael@0: * @param aFirstColGroup - start the reset operation inside this colgroup michael@0: * @param aFirstColIndex - first column that is reset should get this index michael@0: * @param aStartColFrame - if specified the reset starts with this column michael@0: * inside the colgroup; if not specified, the reset michael@0: * starts with the first column michael@0: */ michael@0: static void ResetColIndices(nsIFrame* aFirstColGroup, michael@0: int32_t aFirstColIndex, michael@0: nsIFrame* aStartColFrame = nullptr); michael@0: michael@0: /** michael@0: * Gets inner border widths before collapsing with cell borders michael@0: * Caller must get left border from previous column michael@0: * GetContinuousBCBorderWidth will not overwrite aBorder.left michael@0: * see nsTablePainter about continuous borders michael@0: */ michael@0: void GetContinuousBCBorderWidth(nsMargin& aBorder); michael@0: /** michael@0: * Set full border widths before collapsing with cell borders michael@0: * @param aForSide - side to set; only accepts top and bottom michael@0: */ michael@0: void SetContinuousBCBorderWidth(uint8_t aForSide, michael@0: BCPixelSize aPixelValue); michael@0: michael@0: virtual bool IsFrameOfType(uint32_t aFlags) const MOZ_OVERRIDE michael@0: { michael@0: return nsContainerFrame::IsFrameOfType(aFlags & ~(nsIFrame::eTablePart)); michael@0: } michael@0: michael@0: virtual void InvalidateFrame(uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE; michael@0: virtual void InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey = 0) MOZ_OVERRIDE; michael@0: virtual void InvalidateFrameForRemoval() MOZ_OVERRIDE { InvalidateFrameSubtree(); } michael@0: michael@0: protected: michael@0: nsTableColGroupFrame(nsStyleContext* aContext); michael@0: michael@0: void InsertColsReflow(int32_t aColIndex, michael@0: const nsFrameList::Slice& aCols); michael@0: michael@0: virtual int GetLogicalSkipSides(const nsHTMLReflowState* aReflowState = nullptr) const MOZ_OVERRIDE; michael@0: michael@0: // data members michael@0: int32_t mColCount; michael@0: // the starting column index this col group represents. Must be >= 0. michael@0: int32_t mStartColIndex; michael@0: michael@0: // border width in pixels michael@0: BCPixelSize mTopContBorderWidth; michael@0: BCPixelSize mBottomContBorderWidth; michael@0: }; michael@0: michael@0: inline nsTableColGroupFrame::nsTableColGroupFrame(nsStyleContext *aContext) michael@0: : nsContainerFrame(aContext), mColCount(0), mStartColIndex(0) michael@0: { michael@0: SetColType(eColGroupContent); michael@0: } michael@0: michael@0: inline int32_t nsTableColGroupFrame::GetStartColumnIndex() michael@0: { michael@0: return mStartColIndex; michael@0: } michael@0: michael@0: inline void nsTableColGroupFrame::SetStartColumnIndex (int32_t aIndex) michael@0: { michael@0: mStartColIndex = aIndex; michael@0: } michael@0: michael@0: inline int32_t nsTableColGroupFrame::GetColCount() const michael@0: { michael@0: return mColCount; michael@0: } michael@0: michael@0: inline nsFrameList& nsTableColGroupFrame::GetWritableChildList() michael@0: { michael@0: return mFrames; michael@0: } michael@0: michael@0: #endif michael@0: