Chapter 2 Design Overview
Design Introduction
Objective Grid has an object-oriented architecture. A brief overview of some of these objects and their place in the Objective Grid world helps when working with Objective Grid for the first time.
Three essential objects form the core of the Objective Grid architecture:
*The Style object
*The Range object
*The Parameter object
Each of these objects is discussed in detail in this section.
The Style Object
The style object forms the core for formatting cells in the grid. The style can be seen as an object that completely defines a cell. This means that the style object has all the information necessary for the grid object to draw the cell as well as manage its interaction with users. This includes information such as the font used to draw the cell, the color of the interior, the size of the font, the value displayed, and the type of control in the cell, for example. Style objects for each cell are stored internally by the grid. These can be modified and stored with calls to SetStyleRange(). The sequence of calls to store a style looks like this:
// Declare a style and range object
CGXStyle style;
CGXRange range(1,2,3,4);
// Change it to get the appearance that you want
// Set the value of the cell
// Store the style
SetStyleRange(range, style);
NOTE >> _T() is an MFC macro used to create strings that are portable for ANSI and Unicode builds.
The style object is also capable of initializing itself from other objects, each with a specific function. For example, the font object defines all font specific attributes.
CGXFont font;
font.SetFaceName(_T("Times New Roman"));
On a related note, it is common to see code like the following in Objective Grid sample programs.
This code may seem cryptic at first, but it is actually simple once you understand the concept. Each of these calls returns a reference to the object itself. This allows the programmer to chain several method calls together without explicitly referencing the object each time.
For example, Style.SetInterior() returns a reference to CGXStyle, making it possible for us to call Style.SetInterior().SetValue() all in one stroke.
NOTE >> If you want to remove only the changed background color for a cell style put in place with a SetInterior() call, you can simply call SetIncludeInterior(FALSE).
At this point, it should be clear that cells in a grid are defined by internally stored style objects. These objects can be changed with calls to SetStyleRange().
The styles architecture in Objective Grid goes a little further. Objective Grid divides the styles that it stores into three categories:
*A system-wide standard style.
*A set of user-defined base styles.
*Cell-specific styles.
When the grid draws a cell, it gets the style data in a certain order.
1. The cell-specific style is obtained. The cell-specific style settings override all other style settings.
2. The row and column styles are used to fill any attributes left empty by the cell-specific style.
3. The table-wide style is used to fill any attributes left empty by the row or column styles.
4. The standard grid style is used to continue filling holes.
5. If any base styles are available they are applied. It is important to note that base style settings will always override the grid-wide styles.
Remember, the more specific a style is, the more overriding power it has. Suppose the grid system interior color is white and a base style specifies an interior color of red. The base style color will override the standard style. In short, this architecture allows the grid to have a default initialization hierarchy that is very flexible. This is the basis of the grid virtual mode of operation. The process of gathering these styles is loaded with virtuals that can be overridden to handle the style initialization in a dynamic manner. This is what drives the virtual mode.
The Range Object
This object defines a rectangular range of cells in the grid. It can be set to represent an entire column, an entire row, or the entire table. Explicit coordinates can also be initialized with the top, bottom, left, and right members of the CGXRange object.
Use one of the following methods to specify the range of cells.
*Use CGXRange::SetRows() to specify a range of rows.
*Use CGXRange::SetCols() to specify a range of columns.
*Use CGXRange::SetTable() to specify the full table.
*Use CGXRange::SetCells() to specify individual cells.
One common point of confusion is the difference between the SetCells() call and the SetRows(), SetCols(), and SetTable() calls. SetCells() defines a rectangular region with well defined top-left and bottom-right cells. This is very similar to defining a rectangular region on the screen using CRect.
SetRows(), SetCols(), and SetTable() define regions without a definite top-left or bottom-right cell. Instead they define the range as being entire rows, entire columns, or the entire table, independent of the actual grid dimensions. This means that as the dimensions of the grid grow or shrink, the realized dimensions of the range will grow or shrink. For example, let's say there is a grid with 10 rows and 10 columns, and a range has been defined using SetCols(2,4). The realized coordinates of this range are top = 0, bottom = 10, left = 2, and right = 4.
Figure 2 – CGXRange::SetCols(2,4) in a 10x10 grid
If the last three rows of the grid are removed, the realized coordinates of the same range are now top = 0, bottom =7, left = 2, and right = 4. Note that no changes were made to the original range. It is still defined as SetCols(2,4).
Figure 3 – CGXRange::SetCols(2,4) in a 7x10 grid
Please refer to CGXRange in the Objective Grid Class Reference for more details about how the different ranges are stored in a CGXRange object.
Another common misconception is that you can combine calls to SetRows() and SetCols() to define a cell or range of cells. This is not true. Calling SetRows() defines the range as the specified rows. Following up with a call to SetCols() redefines the range as the specified columns. It does not take the union of the two ranges. To define a cell or range of cells, you must explicitly use SetCells().
The Parameter Object
The parameter object is similar to the document in the MFC document/view paradigm. The parameter object contains or points to all necessary data for persisting the state of the grid object. Parameter objects can be stored in documents and serialized or can be used as members of other classes. Parameter objects can also be shared between grid objects.
The above discussion should make the basic structure of Objective Grid clear. There are several additional objects that Objective Grid uses, but the underlying design philosophy is similar. Understanding these concepts will help in understanding and working with Objective Grid.
The following sections provide a detailed description of the grid architecture.