diff -r 000000000000 -r 6474c204b198 layout/xul/grid/nsGrid.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/layout/xul/grid/nsGrid.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,1299 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// +// Eric Vaughan +// Netscape Communications +// +// See documentation in associated header file +// + +#include "nsGrid.h" +#include "nsGridRowGroupLayout.h" +#include "nsBox.h" +#include "nsIScrollableFrame.h" +#include "nsSprocketLayout.h" +#include "nsGridLayout2.h" +#include "nsGridRow.h" +#include "nsGridCell.h" +#include "nsHTMLReflowState.h" + +/* +The grid control expands the idea of boxes from 1 dimension to 2 dimensions. +It works by allowing the XUL to define a collection of rows and columns and then +stacking them on top of each other. Here is and example. + +Example 1: + + + + + + + + + + + + + +example 2: + + + + + + + + + + + + + + + +example 3: + + + + + + + + + + + + + + + + + + + +Usually the columns are first and the rows are second, so the rows will be drawn on top of the columns. +You can reverse this by defining the rows first. +Other tags are then placed in the or tags causing the grid to accommodate everyone. +It does this by creating 3 things: A cellmap, a row list, and a column list. The cellmap is a 2 +dimensional array of nsGridCells. Each cell contains 2 boxes. One cell from the column list +and one from the row list. When a cell is asked for its size it returns that smallest size it can +be to accommodate the 2 cells. Row lists and Column lists use the same data structure: nsGridRow. +Essentially a row and column are the same except a row goes alone the x axis and a column the y. +To make things easier and save code everything is written in terms of the x dimension. A flag is +passed in called "isHorizontal" that can flip the calculations to the y axis. + +Usually the number of cells in a row match the number of columns, but not always. +It is possible to define 5 columns for a grid but have 10 cells in one of the rows. +In this case 5 extra columns will be added to the column list to handle the situation. +These are called extraColumns/Rows. +*/ + +nsGrid::nsGrid():mBox(nullptr), + mRows(nullptr), + mColumns(nullptr), + mRowsBox(nullptr), + mColumnsBox(nullptr), + mNeedsRebuild(true), + mRowCount(0), + mColumnCount(0), + mExtraRowCount(0), + mExtraColumnCount(0), + mCellMap(nullptr), + mMarkingDirty(false) +{ + MOZ_COUNT_CTOR(nsGrid); +} + +nsGrid::~nsGrid() +{ + FreeMap(); + MOZ_COUNT_DTOR(nsGrid); +} + +/* + * This is called whenever something major happens in the grid. And example + * might be when many cells or row are added. It sets a flag signaling that + * all the grids caches information should be recalculated. + */ +void +nsGrid::NeedsRebuild(nsBoxLayoutState& aState) +{ + if (mNeedsRebuild) + return; + + // iterate through columns and rows and dirty them + mNeedsRebuild = true; + + // find the new row and column box. They could have + // been changed. + mRowsBox = nullptr; + mColumnsBox = nullptr; + FindRowsAndColumns(&mRowsBox, &mColumnsBox); + + // tell all the rows and columns they are dirty + DirtyRows(mRowsBox, aState); + DirtyRows(mColumnsBox, aState); +} + + + +/** + * If we are marked for rebuild. Then build everything + */ +void +nsGrid::RebuildIfNeeded() +{ + if (!mNeedsRebuild) + return; + + mNeedsRebuild = false; + + // find the row and columns frames + FindRowsAndColumns(&mRowsBox, &mColumnsBox); + + // count the rows and columns + int32_t computedRowCount = 0; + int32_t computedColumnCount = 0; + int32_t rowCount = 0; + int32_t columnCount = 0; + + CountRowsColumns(mRowsBox, rowCount, computedColumnCount); + CountRowsColumns(mColumnsBox, columnCount, computedRowCount); + + // computedRowCount are the actual number of rows as determined by the + // columns children. + // computedColumnCount are the number of columns as determined by the number + // of rows children. + // We can use this information to see how many extra columns or rows we need. + // This can happen if there are are more children in a row that number of columns + // defined. Example: + // + // + // + // + // + // + // + //