Back to index

lightning-sunbird  0.9+nobinonly
nsTableCellFrame.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 #ifndef nsTableCellFrame_h__
00038 #define nsTableCellFrame_h__
00039 
00040 #include "nsITableCellLayout.h"
00041 #include "nscore.h"
00042 #include "nsHTMLContainerFrame.h"
00043 #include "nsTableRowFrame.h"  // need to actually include this here to inline GetRowIndex
00044 #include "nsStyleContext.h"
00045 #include "nsIPercentHeightObserver.h"
00046 #include "nsLayoutAtoms.h"
00047 
00048 class nsTableFrame;
00049 
00053 #define NS_TABLE_CELL_CONTENT_EMPTY       0x80000000
00054 #define NS_TABLE_CELL_NEED_SPECIAL_REFLOW 0x40000000
00055 #define NS_TABLE_CELL_HAD_SPECIAL_REFLOW  0x20000000
00056 #define NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT 0x10000000
00057 #define NS_TABLE_CELL_NEED_PASS2_REFLOW   0x08000000
00058 
00070 class nsTableCellFrame : public nsHTMLContainerFrame, 
00071                          public nsITableCellLayout, 
00072                          public nsIPercentHeightObserver
00073 {
00074 public:
00075 
00076   // nsISupports
00077   NS_DECL_ISUPPORTS_INHERITED
00078 
00079   // default constructor supplied by the compiler
00080 
00081   nsTableCellFrame();
00082   ~nsTableCellFrame();
00083 
00084   NS_IMETHOD Init(nsPresContext*  aPresContext,
00085                   nsIContent*      aContent,
00086                   nsIFrame*        aParent,
00087                   nsStyleContext*  aContext,
00088                   nsIFrame*        aPrevInFlow);
00089 
00090 #ifdef ACCESSIBILITY
00091   NS_IMETHOD GetAccessible(nsIAccessible** aAccessible);
00092 #endif
00093 
00094 
00095   NS_IMETHOD  AttributeChanged(nsIContent*     aChild,
00096                                PRInt32         aNameSpaceID,
00097                                nsIAtom*        aAttribute,
00098                                PRInt32         aModType);
00099 
00100   // table cells contain an area frame which does most of the work, and
00101   // so these functions should never be called. They assert and return
00102   // NS_ERROR_NOT_IMPLEMENTED
00103   NS_IMETHOD AppendFrames(nsIAtom*        aListName,
00104                           nsIFrame*       aFrameList);
00105   NS_IMETHOD InsertFrames(nsIAtom*        aListName,
00106                           nsIFrame*       aPrevFrame,
00107                           nsIFrame*       aFrameList);
00108   NS_IMETHOD RemoveFrame(nsIAtom*        aListName,
00109                          nsIFrame*       aOldFrame);
00110 
00111   virtual nsIFrame* GetContentInsertionFrame() {
00112     return GetFirstChild(nsnull)->GetContentInsertionFrame();
00113   }
00114 
00115   virtual void NotifyPercentHeight(const nsHTMLReflowState& aReflowState);
00116 
00117   virtual PRBool NeedsToObserve(const nsHTMLReflowState& aReflowState);
00118 
00124   friend nsresult 
00125   NS_NewTableCellFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
00126 
00127   NS_IMETHOD Paint(nsPresContext*      aPresContext,
00128                    nsIRenderingContext& aRenderingContext,
00129                    const nsRect&        aDirtyRect,
00130                    nsFramePaintLayer    aWhichLayer,
00131                    PRUint32             aFlags = 0);
00132 
00133   NS_IMETHOD GetFrameForPoint(const nsPoint& aPoint, 
00134                               nsFramePaintLayer aWhichLayer,
00135                               nsIFrame**     aFrame);
00136 
00137   NS_IMETHOD SetSelected(nsPresContext* aPresContext,
00138                          nsIDOMRange *aRange,
00139                          PRBool aSelected,
00140                          nsSpread aSpread);
00141 
00142   NS_IMETHOD Reflow(nsPresContext*      aPresContext,
00143                     nsHTMLReflowMetrics& aDesiredSize,
00144                     const nsHTMLReflowState& aReflowState,
00145                     nsReflowStatus&      aStatus);
00146 
00152   virtual nsIAtom* GetType() const;
00153 
00154 #ifdef DEBUG
00155   NS_IMETHOD GetFrameName(nsAString& aResult) const;
00156 #endif
00157 
00158   virtual void VerticallyAlignChild(const nsHTMLReflowState& aReflowState,
00159                                     nscoord                  aMaxAscent);
00160 
00161   PRBool HasVerticalAlignBaseline();
00162 
00169   virtual PRInt32 GetRowSpan();
00170 
00171   // there is no set row index because row index depends on the cell's parent row only
00172 
00173   /*---------------- nsITableCellLayout methods ------------------------*/
00174 
00180   NS_IMETHOD GetCellIndexes(PRInt32 &aRowIndex, PRInt32 &aColIndex);
00181 
00183   virtual nsresult GetRowIndex(PRInt32 &aRowIndex) const;
00184 
00189   NS_IMETHOD GetPreviousCellInColumn(nsITableCellLayout **aCellLayout);
00190 
00195   NS_IMETHOD GetNextCellInColumn(nsITableCellLayout **aCellLayout);
00196 
00203   virtual PRInt32 GetColSpan();
00204   
00206   virtual nsresult GetColIndex(PRInt32 &aColIndex) const;
00207   void SetColIndex(PRInt32 aColIndex);
00208 
00210   virtual nscoord GetPriorAvailWidth();
00211   
00213   virtual void SetPriorAvailWidth(nscoord aPriorAvailWidth);
00214 
00216   virtual nsSize GetDesiredSize();
00217   virtual nscoord GetDesiredAscent();
00218 
00220   virtual void SetDesiredSize(const nsHTMLReflowMetrics & aDesiredSize);
00221 
00223   virtual nscoord GetMaximumWidth() const;
00224 
00226   virtual void SetMaximumWidth(nscoord aMaximumWidth);
00227 
00232   virtual nscoord GetPass1MaxElementWidth() const;
00233 
00237   virtual void SetPass1MaxElementWidth(nscoord aMaxWidth,
00238                                        nscoord aMaxElementWidth);
00239 
00240   PRBool GetContentEmpty();
00241   void SetContentEmpty(PRBool aContentEmpty);
00242 
00243   PRBool NeedSpecialReflow();
00244   void SetNeedSpecialReflow(PRBool aContentEmpty);
00245 
00246   PRBool HadSpecialReflow();
00247   void SetHadSpecialReflow(PRBool aValue);
00248 
00249   PRBool HasPctOverHeight();
00250   void SetHasPctOverHeight(PRBool aValue);
00251 
00252   PRBool NeedPass2Reflow() const;
00253   void SetNeedPass2Reflow(PRBool aValue);
00254 
00255   nscoord GetLastBlockHeight();
00256   void    SetLastBlockHeight(nscoord aValue);
00257 
00258   // The collapse offset is (0,0) except for cells originating in a row/col which is collapsed
00259   void    SetCollapseOffsetX(nscoord aXOffset);
00260   void    SetCollapseOffsetY(nscoord aYOffset);
00261   void    GetCollapseOffset(nsPoint& aOffset);
00262 
00263   nsTableCellFrame* GetNextCell() const;
00264 
00265   virtual nsMargin* GetBorderWidth(float     aPixelsToTwips,
00266                                    nsMargin& aBorder) const;
00267 
00268 protected:
00270   virtual PRIntn GetSkipSides() const;
00271 
00272   virtual PRBool ParentDisablesSelection() const; //override default behavior
00273 
00282   virtual void GetSelfOverflow(nsRect& aOverflowArea);
00283 
00284 private:  
00285 
00286   // All these methods are support methods for RecalcLayoutData
00287   nsIFrame* GetFrameAt(nsVoidArray* aList,  PRInt32 aIndex);
00288 
00289 protected:
00290 
00291   friend class nsTableRowFrame;
00292 
00293   virtual void PaintUnderlay(nsPresContext&           aPresContext,
00294                              nsIRenderingContext&      aRenderingContext,
00295                              const nsRect&             aDirtyRect,
00296                              PRUint32&                 aFlags,
00297                              const nsStyleBorder&      aStyleBorder,
00298                              const nsStylePadding&     aStylePadding,
00299                              const nsStyleTableBorder& aCellTableStyle);
00300 
00301   nsresult  DecorateForSelection(nsPresContext* aPresContext,
00302                                  nsIRenderingContext& aRenderingContext,
00303                                  const nsStyleBackground* aStyleColor);
00304 
00305 protected:
00306 
00307   struct Bits {
00308     PRUint32 mColIndex:15;     
00309     PRUint32 mLastBlockHeight:17;
00310   } mBits;
00311   PRInt32      mColIndex;             // the starting column for this cell 
00312 
00313   // XXX these could be stored as pixels for a savings of 6 x 2 bytes
00314 
00315   nscoord      mPriorAvailWidth;      // the avail width during the last reflow
00316   nsSize       mDesiredSize;          // the last desired width & height
00317   nscoord      mDesiredAscent;        // the last desired ascent
00318   nscoord      mMaximumWidth;         // the last preferred width
00319   nscoord      mPass1MaxElementWidth; // the last max element width
00320 
00321 public:
00322 
00323 #ifdef DEBUG_TABLE_REFLOW_TIMING
00324   nsReflowTimer* mTimer;
00325   nsReflowTimer* mBlockTimer;
00326 #endif
00327 };
00328 
00329 inline nscoord nsTableCellFrame::GetPriorAvailWidth()
00330 { return mPriorAvailWidth;}
00331 
00332 inline void nsTableCellFrame::SetPriorAvailWidth(nscoord aPriorAvailWidth)
00333 { mPriorAvailWidth = aPriorAvailWidth;}
00334 
00335 inline nsSize nsTableCellFrame::GetDesiredSize()
00336 { return mDesiredSize; }
00337 
00338 inline nscoord nsTableCellFrame::GetDesiredAscent()
00339 { return mDesiredAscent; }
00340 
00341 inline void nsTableCellFrame::SetDesiredSize(const nsHTMLReflowMetrics & aDesiredSize)
00342 { 
00343   mDesiredSize.width = aDesiredSize.width;
00344   mDesiredSize.height = aDesiredSize.height;
00345   mDesiredAscent = aDesiredSize.ascent;
00346 }
00347 
00348 inline nscoord nsTableCellFrame::GetMaximumWidth() const
00349 { return mMaximumWidth; }
00350 
00351 inline void nsTableCellFrame::SetMaximumWidth(nscoord aMaximumWidth)
00352 { 
00353   mMaximumWidth = aMaximumWidth;
00354 }
00355 
00356 inline nscoord nsTableCellFrame::GetPass1MaxElementWidth() const
00357 { return mPass1MaxElementWidth; }
00358 
00359 inline PRBool nsTableCellFrame::GetContentEmpty()
00360 {
00361   return (mState & NS_TABLE_CELL_CONTENT_EMPTY) ==
00362          NS_TABLE_CELL_CONTENT_EMPTY;
00363 }
00364 
00365 inline void nsTableCellFrame::SetContentEmpty(PRBool aContentEmpty)
00366 {
00367   if (aContentEmpty) {
00368     mState |= NS_TABLE_CELL_CONTENT_EMPTY;
00369   } else {
00370     mState &= ~NS_TABLE_CELL_CONTENT_EMPTY;
00371   }
00372 }
00373 
00374 inline PRBool nsTableCellFrame::NeedSpecialReflow()
00375 {
00376   return (mState & NS_TABLE_CELL_NEED_SPECIAL_REFLOW) ==
00377          NS_TABLE_CELL_NEED_SPECIAL_REFLOW;
00378 }
00379 
00380 inline void nsTableCellFrame::SetNeedSpecialReflow(PRBool aValue)
00381 {
00382   if (aValue) {
00383     mState |= NS_TABLE_CELL_NEED_SPECIAL_REFLOW;
00384   } else {
00385     mState &= ~NS_TABLE_CELL_NEED_SPECIAL_REFLOW;
00386   }
00387 }
00388 
00389 inline PRBool nsTableCellFrame::HadSpecialReflow()
00390 {
00391   return (mState & NS_TABLE_CELL_HAD_SPECIAL_REFLOW) ==
00392          NS_TABLE_CELL_HAD_SPECIAL_REFLOW;
00393 }
00394 
00395 inline void nsTableCellFrame::SetHadSpecialReflow(PRBool aValue)
00396 {
00397   if (aValue) {
00398     mState |= NS_TABLE_CELL_HAD_SPECIAL_REFLOW;
00399   } else {
00400     mState &= ~NS_TABLE_CELL_HAD_SPECIAL_REFLOW;
00401   }
00402 }
00403 
00404 inline PRBool nsTableCellFrame::HasPctOverHeight()
00405 {
00406   return (mState & NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT) ==
00407          NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT;
00408 }
00409 
00410 inline void nsTableCellFrame::SetHasPctOverHeight(PRBool aValue)
00411 {
00412   if (aValue) {
00413     mState |= NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT;
00414   } else {
00415     mState &= ~NS_TABLE_CELL_HAS_PCT_OVER_HEIGHT;
00416   }
00417 }
00418 
00419 inline PRBool nsTableCellFrame::NeedPass2Reflow() const
00420 {
00421   return (mState & NS_TABLE_CELL_NEED_PASS2_REFLOW) ==
00422          NS_TABLE_CELL_NEED_PASS2_REFLOW;
00423 }
00424 
00425 inline void nsTableCellFrame::SetNeedPass2Reflow(PRBool aValue)
00426 {
00427   if (aValue) {
00428     mState |= NS_TABLE_CELL_NEED_PASS2_REFLOW;
00429   } else {
00430     mState &= ~NS_TABLE_CELL_NEED_PASS2_REFLOW;
00431   }
00432 }
00433 
00434 inline nscoord nsTableCellFrame::GetLastBlockHeight()
00435 {
00436   return (nscoord)mBits.mLastBlockHeight;
00437 }
00438 
00439 inline void nsTableCellFrame::SetLastBlockHeight(nscoord aValue)
00440 {
00441   mBits.mLastBlockHeight = aValue;
00442 }
00443 
00444 // nsBCTableCellFrame
00445 class nsBCTableCellFrame : public nsTableCellFrame
00446 {
00447 public:
00448 
00449   nsBCTableCellFrame();
00450 
00451   ~nsBCTableCellFrame();
00452 
00453   virtual nsIAtom* GetType() const;
00454 
00455   // Get the *inner half of the border only*, in twips.
00456   virtual nsMargin* GetBorderWidth(float     aPixelsToTwips,
00457                                    nsMargin& aBorder) const;
00458 
00459   // Get the *inner half of the border only*, in pixels.
00460   BCPixelSize GetBorderWidth(PRUint8 aSide) const;
00461 
00462   // Set the full (both halves) width of the border
00463   void SetBorderWidth(PRUint8 aSide, BCPixelSize aPixelValue);
00464 
00465   virtual void GetSelfOverflow(nsRect& aOverflowArea);
00466 
00467 #ifdef DEBUG
00468   NS_IMETHOD GetFrameName(nsAString& aResult) const;
00469 #endif
00470 
00471 protected:
00472 
00473   virtual void PaintUnderlay(nsPresContext&           aPresContext,
00474                              nsIRenderingContext&      aRenderingContext,
00475                              const nsRect&             aDirtyRect,
00476                              PRUint32&                 aFlags,
00477                              const nsStyleBorder&      aStyleBorder,
00478                              const nsStylePadding&     aStylePadding,
00479                              const nsStyleTableBorder& aCellTableStyle);
00480 
00481 private:
00482   
00483   // These are the entire width of the border (the cell edge contains only
00484   // the inner half, per the macros in nsTablePainter.h).
00485   BCPixelSize mTopBorder;
00486   BCPixelSize mRightBorder;
00487   BCPixelSize mBottomBorder;
00488   BCPixelSize mLeftBorder;
00489 };
00490 
00491 #endif