Objective Grid : PART I User’s Guide : Chapter 5 Using Objective Grid : Cell and Window Coordinates
Cell and Window Coordinates
Cell and window coordinates are related to each other. It is possible to compute the cell coordinate from a given window point or to compute the window rectangle for a given cell. Hit-Testing is used for determining what is located under a given window coordinate.
Cell Coordinates
The user can scroll the data rows in the view. Column and row headers are fixed at the top and left margins of the window. Optionally, several rows or columns can be frozen so that they never scroll out of the view.
The grid maintains the number of frozen rows and columns and the cell coordinate of the top-left cell. The top-left cell is always located in the first scrollable row and column. All other cell coordinates can be derived from these parameters.
The grid component distinguishes between two coordinate systems:
Relative cell coordinates are numbered from 0 to n in the current visible view.
Absolute cell coordinates are unique identifiers for rows and columns, independent of the current visible view.
A characteristic of headers and frozen rows and columns is that both relative and absolute coordinates are the same value:
Row headers are at column 0.
Column headers are at row 0.
Frozen rows are at row 1 to s, where s equals the number of frozen rows.
Frozen columns are at column 1 to z, where z equals the number of frozen columns.
Figure 45 – Relationship between absolute and relative coordinates
The following CGXGridCore methods can be used to determine or convert coordinates:
GetClientRow(), GetClientCol(), GetRow(), GetCol(), GetTopRow(), GetLeftCol(), GetFrozenRows(), and GetFrozenCols().
Window Coordinates
All column widths, row heights, and font heights are specified in pixels. A typical VGA screen has a resolution of 800x600 or 1024x768 pixels. A printer normally has a considerably higher resolution. To avoid generating much smaller output when printing versus drawing to the screen, Windows uses a technique called coordinate mapping. Objective Grid uses coordinate mapping extensively with its device context.
Device Context
All drawing operations in Microsoft Windows are done through a device context that contains information about the coordinate mapping and drawing attributes, such as font and color. The grid component initializes the mapping mode with 72 pixels per inch for printer output. This is the same value used for screen output. Thus, the developer does not have to consider whether the grid is being displayed to a printer or to the screen when drawing. The coordinate mapping mode for the device context is initialized in CGXGridCore::OnPrepareDC().
Row Heights and Column Widths
Row heights are determined with the overridable method CGXGridCore::GetRowHeight(). Column widths are determined with CGXGridCore::GetColWidth().
Row and column widths are stored internally as logical values. This makes it possible to adapt these values to a change of the zooming factor or standard font size. The following methods in the grid component perform these conversions: CGXGridCore::Height_LPtoDP() and CGXGridCore::Width_LPtoDP() convert logical values to pixel values. CGXGridCore::Height_DPtoLP() and CGXGridCore::Width_DPtoLP() convert pixel values to logical values.
Furthermore, GetRowHeight() and GetColWidth() call the overridable method CGXGridcore::IsRowVisible() or CGXGridCore::IsColVisible() to determine if the specified row or column is visible. In a splitter window, for example, the row headers of the right pane are not visible.
Converting Between Cell and Window Coordinates
It is possible to compute the window rectangle for a given cell because the height and width for each row and column is known. Conversely, it is also possible to determine the cell displayed at a given point.
The following CGXGridCore methods perform the necessary calculations:
CalcClientColFromPt()
Computes the column index for the column displayed at a given window point.
CalcClientRowFromPt()
Computes the row index for the row displayed at a given window point.
CalcRectFromRowCol()
Computes the window rectangle for the given range of cells.
CalcRectFromRowColEx()
Computes the window rectangle for the given range of cells, making sure that covered cells are not cut off.
CalcSumOfColWidths()
CalcSumOfClientColWidths()
Add the width of several columns.
CalcSumOfRowHeights()
CalcSumOfClientRowHeights()
Add the height of several rows.
GetGridRect()
Returns the window area where the grid is drawn. Normally, GetGridRect() determines drawing area by calling the MFC-method GetClientRect(). If the drawing area has been explicitly restricted with SetGridRect() or if the grid is in printing-mode, GetGridRect() returns an internally stored rectangle.
SetGridRect()
Restricts the drawing area to the specified rectangle.
Hit-Testing
Hit-testing is used to determine what is located under a given window coordinate. The method CGXGridCore::HitTest() computes a hit value for a given point.
The following hit values are defined:
GX_HORZLINE - The point is on the gridline of a row header.
GX_VERTLINE - The point is on the gridline of a column header.
GX_HEADERHIT - The point is on the interior rectangle of a row or column header.
GX_CELLHIT - The point is on the interior rectangle of a cell.
GX_SELEDGEHIT - The point is on the edge of a selection. This hit value will only be generated if m_bHitTestSelEdge is TRUE.
GX_NOHIT - No information is displayed at the point
One use of HitTest() is for a context-sensitive mouse cursor. Whenever the mouse is moved, the grid calls HitTest() and changes the mouse cursor as necessary.
NOTE >> GetRowCount() and GetColCount() are used extensively to validate values within routines. In addition, because HitTest() is called repeatedly on every mouse move and because this method touches a lot of grid code, including GetRowCount(), it is not unusual for GetRowCount() to be called thousands of times in a short period of time. Because GetRowCount() and GetColCount() are called quite often, your overrides of these methods are not an appropriate place to do extensive calculation.