/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998 Netscape Communications Corporation. All Rights * Reserved. */ #ifndef BasicTableLayoutStrategy_h__ #define BasicTableLayoutStrategy_h__ #include "nscore.h" #include "nsITableLayoutStrategy.h" #include "nsCoord.h" class nsVoidArray; class nsTableFrame; struct nsStylePosition; struct nsStyleTable; /* ----------- SpanInfo ---------- */ /** SpanInfo is a transient data structure that holds info about * cells that have col spans. Used during column balancing. */ // TODO: collapse this data structure with ColSpanStruct. They both (incompletely) describe // the same situation with slightly different data. struct SpanInfo { PRInt32 span; const PRInt32 initialColSpan; const PRInt32 initialColIndex; nscoord cellMinWidth; nscoord cellDesiredWidth; nscoord effectiveMinWidthOfSpannedCols; nscoord effectiveMaxWidthOfSpannedCols; SpanInfo(PRInt32 aColIndex, PRInt32 aSpan, nscoord aMinWidth, nscoord aDesiredWidth); ~SpanInfo() {}; }; static const PRInt32 kUninitialized=-1; inline SpanInfo::SpanInfo(PRInt32 aColIndex, PRInt32 aSpan, nscoord aMinWidth, nscoord aDesiredWidth) : initialColSpan(aSpan), initialColIndex(aColIndex) { span = aSpan; cellMinWidth = aMinWidth; cellDesiredWidth = aDesiredWidth; effectiveMinWidthOfSpannedCols=kUninitialized; effectiveMaxWidthOfSpannedCols=kUninitialized; } /* ---------- BasicTableLayoutStrategy ---------- */ /** Implementation of Nav4 compatible HTML browser table layout. * The input to this class is the results from pass1 table layout. * The output from this class is to set the column widths in * mTableFrame. */ class BasicTableLayoutStrategy : public nsITableLayoutStrategy { public: /** Public constructor. * @paran aFrame the table frame for which this delegate will do layout */ BasicTableLayoutStrategy(nsTableFrame *aFrame, PRBool aIsNavQuirksMode = PR_TRUE); /** destructor */ virtual ~BasicTableLayoutStrategy(); /** call every time any table thing changes that might effect the width of any column * in the table (content, structure, or style) * @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param * @param aNumCols the total number of columns in the table */ virtual PRBool Initialize(nsSize* aMaxElementSize, PRInt32 aNumCols, nscoord aMaxSize); /** compute the max element size of the table. * assumes that Initialize has been called */ virtual void SetMaxElementSize(nsSize* aMaxElementSize); /** Called during resize reflow to determine the new column widths * @param aTableStyle - the resolved style for mTableFrame * @param aReflowState - the reflow state for mTableFrame * @param aMaxWidth - the computed max width for columns to fit into */ virtual PRBool BalanceColumnWidths(nsIStyleContext * aTableStyle, const nsHTMLReflowState& aReflowState, nscoord aMaxWidth); // these accessors are mostly for debugging purposes nscoord GetTableMinWidth() const; nscoord GetTableMaxWidth() const; nscoord GetTableFixedWidth() const; nscoord GetCOLSAttribute() const; nscoord GetNumCols() const; protected: /** assign widths for each column. * if the column has a fixed coord width, use it. * if the column includes col spanning cells, * then distribute the fixed space between cells proportionately. * Computes the minimum and maximum table widths. * Set column width information in each column frame and in the table frame. * * @param aMaxWidth - the computed width of the table or * UNCONSTRAINED_SIZE if an auto width table * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error * */ virtual PRBool AssignPreliminaryColumnWidths(nscoord aComputedWidth); /** compute the min and max width of this table. Assumes AssignPreliminaryColumnWidths * has been called. Sets mMinTableWidth and mMaxTableWidth as a side effect. */ virtual void SetMinAndMaxTableWidths(); /** assign widths for each column within a particular context. * The context is given by each of the parameters. * Sets mTableFrame->mColumnWidths as a side effect. * * @param aReflowState the reflow state * @param aAvailWidth the remaining amount of horizontal space available * @param aMaxWidth the total amount of horizontal space available * @param aTableSpecifiedWidth the width of the table based on its attributes and its parent's width * @param aTableIsAutoWidth PR_TRUE if the table is auto-width * * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error * */ virtual PRBool BalanceProportionalColumns(const nsHTMLReflowState& aReflowState, nscoord aAvailWidth, nscoord aMaxWidth, nscoord aTableSpecifiedWidth, PRBool aTableIsAutoWidth); /** assign the minimum legal width for each column that has proportional width. * Typically called when the min table width doesn't fit in the available space. * Sets mTableFrame->mColumnWidths as a side effect. * * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error */ virtual PRBool BalanceColumnsTableDoesNotFit(); /** assign the maximum allowed width for each column. * Typically called when the desired max table width is less than or equal to the available space. * Sets mTableFrame->mColumnWidths as a side effect. * * @param aReflowState the reflow state * @param aAvailWidth the remaining amount of horizontal space available * @param aMaxWidth the total amount of horizontal space available * @param aTableSpecifiedWidth the specified width of the table. If there is none, * this param is 0 * @param aTableIsAutoWidth PR_TRUE if the table is auto-width * * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error */ virtual PRBool BalanceColumnsTableFits(const nsHTMLReflowState& aReflowState, nscoord aAvailWidth, nscoord aMaxWidth, nscoord aTableSpecifiedWidth, PRBool aTableIsAutoWidth); /** for each column, assign a width between the column's minimum and maximum width. * Typically called when the desired max table width is greater the available space. * Sets mTableFrame->mColumnWidths as a side effect. * * @param aReflowState the reflow state * @param aAvailWidth the remaining amount of horizontal space available * @param aMaxWidth the total amount of horizontal space available * @param aTableIsAutoWidth PR_TRUE if the table is auto-width * * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error * */ virtual PRBool BalanceColumnsConstrained(const nsHTMLReflowState& aReflowState, nscoord aAvailWidth, nscoord aMaxWidth, PRBool aTableIsAutoWidth); /** post-process to AssignFixedColumnWidths * * @param aColSpanList a list of fixed-width columns that have colspans * * NOTE: does not yet properly handle overlapping col spans in all cases * * @return void */ virtual void DistributeFixedSpace(nsVoidArray *aColSpanList); /** starting with a partially balanced table, compute the amount * of space to pad each column by to completely balance the table. * Sets mTableFrame->mColumnWidths as a side effect. * * @param aAvailWidth the space still to be allocated within the table * @param aTableWidth the sum of all columns widths * @param aWidthOfFixedTableColumns the sum of the widths of fixed-width columns * * @return void */ virtual void DistributeExcessSpace(nscoord aAvailWidth, nscoord aTableWidth, nscoord aWidthOfFixedTableColumns); /** starting with a partially balanced table, compute the amount * of space to allocate to each column to completely balance the table. * set the column widths in mTableFrame based on these computations. * assumes auto-width columns have been set to their minimum width. * must be called with a PRInt32 variable initialized to 0 for aRecursionControl. * * @param aTableFixedWidth the specified width of the table. If there is none, * this param is 0 * @param aComputedTableWidth IN: the width of the table before this step. * OUT:the width of the table after this step. * @param aTableIsAutoWidth TRUE if the table style indicates it is autoWidth * @param aRecursionControl IN: must be a PRInt32 set to 0 * OUT: the number of iterations. Not generally useful to the caller, * but useful for limiting the number of iterations in bizarre cases. * * @return void */ virtual void DistributeRemainingSpace(nscoord aTableFixedWidth, nscoord &aComputedTableWidth, PRBool aTableIsAutoWidth); virtual void AdjustTableThatIsTooWide(nscoord aComputedWidth, nscoord aTableWidth, PRBool aShrinkFixedCols); virtual void AdjustTableThatIsTooNarrow(nscoord aComputedWidth, nscoord aTableWidth); /** return true if the style indicates that the width is a specific width * for the purposes of column width determination. * return false if the width changes based on content, parent size, etc. */ static PRBool IsFixedWidth(const nsStylePosition* aStylePosition, const nsStyleTable* aStyleTable); /** return true if the colIndex is in the list of colIndexes */ virtual PRBool IsColumnInList(const PRInt32 colIndex, PRInt32 *colIndexes, PRInt32 aNumFixedColumns); /** returns true if the column is specified to have its min width */ virtual PRBool ColIsSpecifiedAsMinimumWidth(PRInt32 aColIndex); /** eturns a list and count of all columns that behave like they have width=auto * this includes columns with no width specified (the normal definition of "auto"), * columns explicitly set to auto width, * and columns whose fixed width comes from a span (meaning the real width is indeterminate.) * * @param aOutNumColumns -- out param, the number of columns matching aType * @param aOutColumnIndexes -- out param, the indexes of the columns matching aType * * @return aOutNumColumns set to the number of auto columns, may be 0 * allocates and fills aOutColumnIndexes * caller must "delete [] aOutColumnIndexes" if it is not null */ void GetColumnsThatActLikeAutoWidth(PRInt32& aOutNumColumns, PRInt32*& aOutColumnIndexes); nscoord CalcHorizontalPadding(PRInt32 aColX); protected: nsTableFrame * mTableFrame; PRInt32 mCols; PRInt32 mNumCols; // cached data nscoord mMinTableWidth; // the smallest size for the table nscoord mMaxTableWidth; // the "natural" size for the table, if unconstrained nscoord mFixedTableWidth; // the amount of space taken up by fixed-width columns PRBool mIsNavQuirksMode; }; // these accessors are mostly for debugging purposes inline nscoord BasicTableLayoutStrategy::GetTableMinWidth() const { return mMinTableWidth; }; inline nscoord BasicTableLayoutStrategy::GetTableMaxWidth() const { return mMaxTableWidth; }; inline nscoord BasicTableLayoutStrategy::GetTableFixedWidth() const { return mFixedTableWidth; }; inline nscoord BasicTableLayoutStrategy::GetCOLSAttribute() const { return mCols; }; inline nscoord BasicTableLayoutStrategy::GetNumCols() const { return mNumCols; }; #endif