IMultiCellCanvas

The IMultiCellCanvas class manages a collection of child windows in a way similar to that of data stored in a spreadsheet. A multicell canvas is a two-dimensional array of cells with an origin of (1,1) in the upper-left corner. Windows are added to a multicell canvas by specifying a starting cell and, optionally, a number of contiguous columns, rows, or a combination thereof.

This class bases the initial cell sizes on the minimum sizes returned by each child window of the canvas. You can override the minimum sizes provided by the Open Class Library by doing either of the following:

Changing the size of a multicell canvas causes only expandable rows and columns to be resized. The user can cause any occupied cells to be resized by doing either of the following:

Undesirable movement of the windows might result when a multicell canvas updates its child windows. In the case where the canvas contains IStaticText windows, you can avoid this by calling IStaticText::setLimit so that the static text bases its minimum size on an expected number of characters rather than its actual text string.

The following figure illustrates the positioning of four static text controls, three entry fields, and two push buttons:
Sample Multicell Canvas

Because there is no text in either row 1 or column 1, row 1 and column 1 take the default cell size, which is 10 pixels. As you can see in the figure, the default cell size is relatively small and, therefore, preserves screen space. Also, using the default cell size for column 1 and row 1 creates some padding, or margin, around the child windows that you place in the multicell canvas.

Positioning Static Text Controls Example

The first static text control has a starting cell of (2,2). The child static text control window exists in one row, row 2, and extends from column 2 through column 7. It occupies six columns (2, 3, 4, 5, 6, and 7). The following addToCell call was used to produce it, where myClient is the client window multicell canvas:

myClient.addToCell(&prompt, 2, 2, 6, 1);

The name of the child static text control window is prompt. The two numbers that follow the name specify the starting column and row, (2,2). The last two numbers, (6,1), specify that the control extends through six columns and occupies one row.

The other static text controls, which contain the text strings "Name," "Serial number," and "Password," have starting cells of (3,4), (3,6), and (3,8), respectively. The following addToCell calls were used to produce them:

myClient.addToCell(&namePrompt, 3, 4);
myClient.addToCell(&numberPrompt, 3, 6);
myClient.addToCell(&passwordPrompt, 3, 8);

Notice that we did not specify the number of columns and rows for these text controls to occupy. This means the columns and rows take the default, which is one column and one row. The width of column 3 is based on the static text control that contains "Serial number."

Positioning Entry Fields Example

The first entry field has a starting cell of (5,4) and extends through three columns (columns 5, 6, and 7) while occupying one row. The first static text control has already determined the width of these columns, so this entry field is stretched to the right edge of column 7.

The second entry field has a starting cell of (5,6) and occupies the default of one column and one row. This means that the width of column 5 is based on the width of the second entry field because it only occupies one column.

The third entry field has a starting cell of (5,8), spanning two columns and one row. Here are the addToCell calls for the entry fields:

myClient.addToCell(&name, 5, 4, 3, 1);
myClient.addToCell(&number, 5, 6);
myClient.addToCell(&password, 5, 8, 2, 1);

Using Expandable Rows and Columns Example

In the figure, column 7 is much wider than you might expect. You might think that it should be the same size as all of the other columns except 3 and 5, which are sized to fit particular controls. Also, the height of row 9 is much greater than that of the other rows. The reason column 7 is so much wider and that the height of row 9 is so much greater is that we made them expandable. Columns and rows that are expandable grow when the window's size increases or shrink when the window's size decreases.

When the space allotted to the canvas is larger than the size needed to contain the canvas, expandable rows and columns are given more space relative to each other. For example, if one expandable row is twice the size of another expandable row, the ratio is maintained after increasing the size of the canvas. Rows and columns that are not specified as expandable maintain their fixed size.

The setColumnWidth and setRowHeight functions have an expandable parameter whose default is false. However, we set them to true for column 7 and row 9. Here is the setColumnWidth function call for column 7:

myClient.setColumnWidth(7, 0, true);

On the setColumnWidth function call, the first number represents column 7. The second number specifies the amount that the width of the column is to increase beyond the minimum size required for the window or windows contained in the column. We set this to 0 so that the column would not take up screen space unless the canvas is wide enough that it has space not needed by the nonexpandable columns. The final value, true, indicates that this column is expandable.

Positioning Push Buttons Example

The last part of this multicell canvas is actually another multicell canvas. The two push buttons, OK and Cancel, are contained in a multicell canvas that is nested inside the multicell canvas that contains the other controls. To do this, we first defined a nested multicell canvas called myButtons and added it to the bottom of the myClient multicell canvas:

myClient.addToCell(&myButtons, 2, 10, 6, 1);

The myButtons canvas begins in column 2, row 10, and spans six columns and one row. Next, we used the addToCell function to put the two push buttons in the myButtons canvas, as follows:

myButtons.addToCell(&ok, 1, 1);
myButtons.addToCell(&cancel, 3, 1);

The OK push button begins in column 1, row 1 of the nested canvas and occupies one column. In the figure, the white numbers in black boxes indicate the columns and rows in the nested canvas. The Cancel push button begins in column 3, row 1 of the nested canvas and also spans one column. The width of the columns is determined by the size of the text in the push buttons together with the margin around the text (the space between the text and the border of the push buttons).

You must specify the last row and column of a multicell canvas on either an addToCell call or on setRowHeight and setColumnWidth calls. This is done to provide a padding, or margin, for the right and bottom sides of the canvas, similar to the margin provided by taking the default cell size for column 1 and row 1. The following are the calls used in the example to set the last column and row, column 8 and row 11, to the default column width and row height:

myClient.setColumnWidth(8, IMultiCellCanvas::defaultCell().width());
myClient.setRowHeight(11, IMultiCellCanvas::defaultCell().height());

The following points are from the preceding example:

Portability Considerations

You can create child windows of an IMultiCellCanvas which are not added to any cells of the IMultiCellCanvas. The IMultiCellCanvas, however, will only perform positioning of child controls that are added to the canvas. Therefore, the positioning of child controls that are not added to the canvas may vary from platform to platform because coordinate system differences are not handled automatically.

You can avoid this problem by ensuring that all visible child controls are added to the canvas.


IMultiCellCanvas - Member Functions and Data by Group

Constructors & Destructor

You can construct and destruct objects of this class. You cannot copy or assign IMultiCellCanvas objects because both the copy constructor and assignment operator are private functions.


[view class]
~IMultiCellCanvas
public:
virtual ~IMultiCellCanvas()

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
IMultiCellCanvas
public:
IMultiCellCanvas( unsigned long windowIdentifier, IWindow* parent, IWindow* owner, const IRectangle& initialSize = IRectangle ( ), const Style& style = defaultStyle ( ) )
windowIdentifier
The window identifier of the canvas you are constructing.

We recommend that you do the following:

  • For portability, use a value in the range 0 to 65535.
  • Give unique identifiers to all windows in the same frame window. Two windows are in the same frame window if the first frame window in each of its parent window chains is the same window.
  • Give the client window a window identifier of IC_FRAME_CLIENT_ID, which is defined in the file icconst.h.

Presentation Manager Notes Do not use FID_xxx values defined in pmwin.h, other than FID_CLIENT (which is equivalent to IC_FRAME_CLIENT_ID).
parent
The parent window of the canvas you are constructing. You must specify a parent window. The parent window is primarily used for visible relationships.
owner
The owner window of the canvas you are constructing. The owner window is primarily used for routing notification events and unprocessed messages. A window also inherits colors from its owner window.
Motif Notes The owner window is only used for routing unprocessed messages. There is no concept of an owner in Motif.
initialSize
The initial position and size of the canvas you are constructing. The position is relative to the origin of the parent window. See ICoordinateSystem for additional information. Optional.
style
The window's characteristics. This value can be a combination of IMultiCellCanvas::Style, ICanvas::Style, and IWindow::Style objects. Optional.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


Cell Contents

Use these members to position child windows of the canvas relative to one another, in cells.


[view class]
addToCell
public:
virtual IMultiCellCanvas& addToCell( IWindow* childWindow, unsigned long startingColumn, unsigned long startingRow, unsigned long numberOfColumns = 1, unsigned long numberOfRows = 1 )

Specifies the starting cell into which a window is placed. Optionally, you can specify the number of columns or rows that the window occupies. By default, a multicell canvas has no windows. Windows added to the multicell canvas must be parented to the multicell canvas or an InvalidParameter exception is thrown.
Note: If the multicell canvas is already shown, this function does not cause it to update the canvas itself immediately. You must call IWindow::refresh to update the appearance of the canvas.

You do not specify how many rows and columns a multicell canvas contains. IMultiCellCanvas determines the maximum number of rows and columns from addToCell, setColumnWidth, and setRowHeight.

Exception

IInvalidRequest The canvas already contains a child window that begins in the cell identified by startingColumn and startingRow.
IInvalidParameter childWindow must be a nonzero pointer.
IInvalidParameter childWindow must be a child window of the multicell canvas.
IInvalidParameter startingColumn, startingRow, numberOfColumns, and numberofRows must be nonzero.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
removeFromCell

Removes a window from the canvas. If you specify a cell, the window that occupies that cell is removed. If you specify a window, the window is removed.

This function returns the window removed from the canvas. It does not delete the child window. If the specified window is not found, 0 is returned.

You must call this function if you delete the child window or change its parent window.
Note: If the multicell canvas is already shown, this function does not cause it to update immediately. You must call IWindow::refresh to update the appearance of the canvas.


Overload 1
public:
virtual IWindow* removeFromCell(IWindow* childWindow)
childWindow
The child window to remove from the multicell canvas.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


Overload 2
public:
virtual IWindow* removeFromCell( unsigned long column, unsigned long row )
column
The starting column of the child window being removed. Columns are numbered beginning with 1. This is the starting column you specified in the addToCell call that added the child window to the canvas.
row
The starting row of the child window being removed. Rows are numbered beginning with 1. This is the starting row you specified in the addToCell call that added the child window to the canvas.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
windowInCell
public:
virtual IWindow* windowInCell( unsigned long startingColumn, unsigned long startingRow ) const

Returns the child window occupying the specified cell.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


Grid and Drag Lines

These members provide visual debugging aids for you to use in your IMultiCellCanvas objects.


[view class]
disableDragLines
public:
virtual IMultiCellCanvas& disableDragLines()

Removes the style IMultiCellCanvas::dragLines from a multicell canvas.

Supported Platforms

Windows OS/2 AIX
Yes Yes Ignored


[view class]
disableGridLines
public:
virtual IMultiCellCanvas& disableGridLines()

Removes the style IMultiCellCanvas::gridLines from a multicell canvas.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
enableDragLines
public:
virtual IMultiCellCanvas& enableDragLines( bool enable = true )

Sets the style IMultiCellCanvas::dragLines for a multicell canvas.

Supported Platforms

Windows OS/2 AIX
Yes Yes Ignored


[view class]
enableGridLines
public:
virtual IMultiCellCanvas& enableGridLines( bool enable = true )

Sets the style IMultiCellCanvas::gridLines for a multicell canvas.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
hasDragLines
public:
bool hasDragLines() const

Queries whether a multicell canvas has the style IMultiCellCanvas::dragLines set.

Supported Platforms

Windows OS/2 AIX
Yes Yes Ignored


[view class]
hasGridLines
public:
bool hasGridLines() const

Queries whether a multicell canvas has the style IMultiCellCanvas::gridLines set.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


Layout Support

Use layout members to determine how this class sizes and positions its child windows or how this window will be laid out on another canvas.


[view class]
hasChildrenToLayout
public:
virtual bool hasChildrenToLayout() const

Indicates whether the canvas is managing the size and position of any child windows.

This function returns true if the canvas contains at least one child window that you have specified on a call to addToCell. Otherwise it returns false.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
setLayoutDistorted
public:
virtual IMultiCellCanvas& setLayoutDistorted( unsigned long layoutAttributesOn, unsigned long layoutAttributesOff )

Adds the IWindow::layoutDistorted flag to its internal state if it receives a value of IWindow::childWindowCreated or IWindow::childWindowDestroyed and calls IWindow::setLayoutDistorted. If the IWindow::immediateUpdate flag is on, the canvas runs its layout routine.

The internal state of a window is indicated by the Layout enumeration.

A window treats the following events as changes to the layout of its child windows:

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
layout
protected:
virtual IMultiCellCanvas& layout()

Computes the child windows' positions and sizes based on the following:

Then positions and sizes each child according to the results.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


Row and Column Sizing

Use these members to query and set the width of columns and the height of rows in the canvas, as well as to set their ability to expand with the canvas.


[view class]
columnWidth
public:
unsigned long columnWidth(unsigned long column) const

Returns the current width of the specified column in pixels.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
defaultCell
public:
static ISize defaultCell()

Queries the current default cell size. The initial default size is 10 pixels by 10 pixels. You can change it by calling the function setDefaultCell.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
isColumnExpandable
public:
bool isColumnExpandable(unsigned long column) const

If the specified column can be expanded when the canvas is larger than its minimum size, true is returned. You can use setColumnWidth to make a column expandable.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
isRowExpandable
public:
bool isRowExpandable(unsigned long row) const

If the specified row can be expanded when the canvas is larger than its minimum size, true is returned. You can use setRowHeight to make a row expandable.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
rowHeight
public:
unsigned long rowHeight(unsigned long row) const

Returns the current height of the specified row in pixels.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
setColumnWidth
public:
virtual IMultiCellCanvas& setColumnWidth( unsigned long column, unsigned long widthInPixels, bool expandable = false )

Defines the smallest width that the column will have and indicates whether the column is expandable. The minimum sizes of the child windows in this column might cause the actual width of this column to be larger than this value.

If you do not call this function, the column will have a minimum width of 0 unless the column contains no child windows. In that case, the canvas sizes the column to the default cell width.

You do not specify how many rows and columns a multicell canvas contains. IMultiCellCanvas determines the maximum number of rows and columns from addToCell, setColumnWidth, and setRowHeight.
Note: If the multicell canvas is already shown, this function does not cause it to update itself immediately. You must call IWindow::refresh to update the appearance of the canvas.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
setDefaultCell
public:
static void setDefaultCell(const ISize& widthAndHeight)

Sets the default width for a column and height for a row of a cell that does not have a child window. The initial default size for both rows and columns is 10 pixels.
Note: This function does not cause the layout of a multicell canvas to update itself immediately. To force a multicell canvas to update after calling this function, call setLayoutDistorted, as follows:

setLayoutDistorted(IWindow::layoutChanged |
                        IWindow::immediateUpdate, 0);

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
setRowHeight
public:
virtual IMultiCellCanvas& setRowHeight( unsigned long row, unsigned long heightInPixels, bool expandable = false )

Defines the smallest height that the row will have and indicates whether the row is expandable. The minimum sizes of the child windows in this row can cause the actual height of the row to be larger than this value.

If you do not call this function, the row will have a minimum height of 0 unless the row contains no child windows. In that case, the canvas sizes the row to the default cell height.

You do not specify how many rows and columns a multicell canvas contains. IMultiCellCanvas determines the maximum number of rows and columns from addToCell, setColumnWidth, and setRowHeight.
Note: If a multicell canvas is already shown, this function does not cause it to update itself immediately. You must call IWindow::refresh to update the appearance of the canvas.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


Styles

Use these style members to customize a window at the time you construct it. Most styles have equivalent member functions, which allow you to similarly modify a window after creating it. You can use these styles with the styles defined by the following nested classes:

Once you have constructed an IMultiCellCanvas object, you can use IMultiCellCanvas, ICanvas, and IWindow member functions to query and change individual styles.


[view class]
convertToGUIStyle
public:
virtual unsigned long convertToGUIStyle( const IBitFlag& style, bool extendedOnly = false ) const

Converts a style object into a value appropriate for the underlying system. The default action is to return the base GUI styles for the platform. Extended styles, those defined by the application and the Open Class Library, will be returned if you set extendedOnly to true.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
defaultStyle
public:
static Style defaultStyle()

Returns the default style. The default style is classDefaultStyle unless you have changed the style using setDefaultStyle.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
setDefaultStyle
public:
static void setDefaultStyle(const Style& style)

Sets the default style for all subsequent multicell canvases.

This member function is not thread safe. In a multithreaded application, it should only be called when a conflict is not possible. A conflict can arise if you set the default style on one thread at the same time that it is being queried on another. In this situation, the query would take place while the style is in an unknown state.

When you create a window class and do not specifically specify window styles in the constructor, the Open Class Library queries the default style. Therefore, the only safe place to call this member function is when no other application threads that create windows are active.

Another way to avoid a conflict in a multithreaded application is to specifically specify window styles on window construction, rather than calling this member function.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
classDefaultStyle
public:
static const Style classDefaultStyle

Specifies the original default style for this class, which is IWindow::visible.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
dragLines
public:
static const Style dragLines

Causes the multicell canvas to have draggable grid lines between the rows and columns of the canvas. Dragging and dropping grid lines will dynamically cause the functions setColumnWidth and setRowHeight to be called, adjusting the size of bounding rows and columns. This is a visual enhancement that is intended to be used for testing or debugging purposes only.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
gridLines
public:
static const Style gridLines

Causes the multicell canvas to have grid lines between the rows and columns of the canvas.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


[view class]
spaceAddedToLast
public:
static const Style spaceAddedToLast

Causes the multicell canvas to size its columns and rows in an alternate manner.

This style affects child windows that occupy more than one column or row, of which none are expandable. If the sum of the columns occupied by the child window is less than the minimum width of the child window, or the sum of the rows is less than the minimum height of the child window, then the multicell canvas must grow one of the columns or rows. By default, IMultiCellCanvas grows the first column and row occupied by the child window. If you use this style, the canvas instead grows the last column or row occupied by the child window. In some cases, this results in more predictable layouts.

Supported Platforms

Windows OS/2 AIX
Yes Yes Yes


IMultiCellCanvas - Inherited Member Functions and Data

Inherited Public Functions

ICanvas
IControl
INotifier
IWindow

Inherited Public Data

IWindow
INotifier
ICanvas

Inherited Protected Functions

IWindow
INotifier
ICanvas
IControl

Inherited Protected Data