1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef nsGrid_h___
8 #define nsGrid_h___
9 
10 #include "nsStackLayout.h"
11 #include "nsIGridPart.h"
12 #include "nsCOMPtr.h"
13 #include "mozilla/UniquePtr.h"
14 
15 class nsBoxLayoutState;
16 class nsGridCell;
17 
18 //#define DEBUG_grid 1
19 
20 /**
21  * The grid data structure, i.e., the grid cellmap.
22  */
23 class nsGrid {
24  public:
25   nsGrid();
26   ~nsGrid();
27 
28   nsGridRow* GetColumnAt(int32_t aIndex, bool aIsHorizontal = true);
29   nsGridRow* GetRowAt(int32_t aIndex, bool aIsHorizontal = true);
30   nsGridCell* GetCellAt(int32_t aX, int32_t aY);
31 
32   void NeedsRebuild(nsBoxLayoutState& aBoxLayoutState);
33   void RebuildIfNeeded();
34 
35   // For all the methods taking an aIsHorizontal parameter:
36   // * When aIsHorizontal is true, the words "rows" and (for
37   //   GetColumnCount) "columns" refer to their normal meanings.
38   // * When aIsHorizontal is false, the meanings are flipped.
39   // FIXME:  Maybe eliminate GetColumnCount and change aIsHorizontal to
40   // aIsRows?  (Calling it horizontal doesn't really make sense because
41   // row groups and columns have vertical orientation, whereas column
42   // groups and rows are horizontal.)
43 
44   nsSize GetPrefRowSize(nsBoxLayoutState& aBoxLayoutState, int32_t aRowIndex,
45                         bool aIsHorizontal = true);
46   nsSize GetMinRowSize(nsBoxLayoutState& aBoxLayoutState, int32_t aRowIndex,
47                        bool aIsHorizontal = true);
48   nsSize GetMaxRowSize(nsBoxLayoutState& aBoxLayoutState, int32_t aRowIndex,
49                        bool aIsHorizontal = true);
50   nscoord GetRowFlex(int32_t aRowIndex, bool aIsHorizontal = true);
51 
52   nscoord GetPrefRowHeight(nsBoxLayoutState& aBoxLayoutState, int32_t aRowIndex,
53                            bool aIsHorizontal = true);
54   nscoord GetMinRowHeight(nsBoxLayoutState& aBoxLayoutState, int32_t aRowIndex,
55                           bool aIsHorizontal = true);
56   nscoord GetMaxRowHeight(nsBoxLayoutState& aBoxLayoutState, int32_t aRowIndex,
57                           bool aIsHorizontal = true);
58   void GetRowOffsets(int32_t aIndex, nscoord& aTop, nscoord& aBottom,
59                      bool aIsHorizontal = true);
60 
61   void RowAddedOrRemoved(nsBoxLayoutState& aBoxLayoutState, int32_t aIndex,
62                          bool aIsHorizontal = true);
63   void CellAddedOrRemoved(nsBoxLayoutState& aBoxLayoutState, int32_t aIndex,
64                           bool aIsHorizontal = true);
65   void DirtyRows(nsIFrame* aRowBox, nsBoxLayoutState& aState);
66 #ifdef DEBUG_grid
67   void PrintCellMap();
68 #endif
69   int32_t GetExtraColumnCount(bool aIsHorizontal = true);
70   int32_t GetExtraRowCount(bool aIsHorizontal = true);
71 
72   // accessors
SetBox(nsIFrame * aBox)73   void SetBox(nsIFrame* aBox) { mBox = aBox; }
GetBox()74   nsIFrame* GetBox() { return mBox; }
GetRowsBox()75   nsIFrame* GetRowsBox() { return mRowsBox; }
GetColumnsBox()76   nsIFrame* GetColumnsBox() { return mColumnsBox; }
77   int32_t GetRowCount(int32_t aIsHorizontal = true);
78   int32_t GetColumnCount(int32_t aIsHorizontal = true);
79 
80   static nsIFrame* GetScrolledBox(nsIFrame* aChild);
81   static nsIFrame* GetScrollBox(nsIFrame* aChild);
82   static nsIGridPart* GetPartFromBox(nsIFrame* aBox);
83   void GetFirstAndLastRow(int32_t& aFirstIndex, int32_t& aLastIndex,
84                           nsGridRow*& aFirstRow, nsGridRow*& aLastRow,
85                           bool aIsHorizontal);
86 
87  private:
88   nsMargin GetBoxTotalMargin(nsIFrame* aBox, bool aIsHorizontal = true);
89 
90   void FreeMap();
91   void FindRowsAndColumns(nsIFrame** aRows, nsIFrame** aColumns);
92   mozilla::UniquePtr<nsGridRow[]> BuildRows(nsIFrame* aBox, int32_t aSize,
93                                             bool aIsHorizontal = true);
94   mozilla::UniquePtr<nsGridCell[]> BuildCellMap(int32_t aRows,
95                                                 int32_t aColumns);
96   void PopulateCellMap(nsGridRow* aRows, nsGridRow* aColumns, int32_t aRowCount,
97                        int32_t aColumnCount, bool aIsHorizontal = true);
98   void CountRowsColumns(nsIFrame* aBox, int32_t& aRowCount,
99                         int32_t& aComputedColumnCount);
100   void SetLargestSize(nsSize& aSize, nscoord aHeight,
101                       bool aIsHorizontal = true);
102   void SetSmallestSize(nsSize& aSize, nscoord aHeight,
103                        bool aIsHorizontal = true);
104   bool IsGrid(nsIFrame* aBox);
105 
106   // the box that implement the <grid> tag
107   nsIFrame* mBox;
108 
109   // an array of row object
110   mozilla::UniquePtr<nsGridRow[]> mRows;
111 
112   // an array of columns objects.
113   mozilla::UniquePtr<nsGridRow[]> mColumns;
114 
115   // the first in the <grid> that implements the <rows> tag.
116   nsIFrame* mRowsBox;
117 
118   // the first in the <grid> that implements the <columns> tag.
119   nsIFrame* mColumnsBox;
120 
121   // a flag that is false tells us to rebuild the who grid
122   bool mNeedsRebuild;
123 
124   // number of rows and columns as defined by the XUL
125   int32_t mRowCount;
126   int32_t mColumnCount;
127 
128   // number of rows and columns that are implied but not
129   // explicitly defined int he XUL
130   int32_t mExtraRowCount;
131   int32_t mExtraColumnCount;
132 
133   // x,y array of cells in the rows and columns
134   mozilla::UniquePtr<nsGridCell[]> mCellMap;
135 
136   // a flag that when true suppresses all other MarkDirties. This
137   // prevents lots of extra work being done.
138   bool mMarkingDirty;
139 };
140 
141 #endif
142