* * Table widget by David Harrison, University of California, Berkeley. * Copyright (C) 1994, Enterprise Integration Technologies Corp. and Niels Mayer. * WINTERP 1.15-1.99, Copyright (c) 1993, Niels P. Mayer. * WINTERP 1.0-1.14, Copyright (c) 1989-1992 Hewlett-Packard Co. and Niels Mayer. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Enterprise Integration Technologies, * Hewlett-Packard Company, Niels Mayer, and David Harrison not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Enterprise Integration Technologies, * Hewlett-Packard Company, Niels Mayer, and David Harrison makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * ENTERPRISE INTEGRATION TECHNOLOGIES, HEWLETT-PACKARD COMPANY, NIELS MAYER, * AND DAVID HARRISON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT * SHALL ENTERPRISE INTEGRATION TECHNOLOGIES, HEWLETT-PACKARD COMPANY, NIELS * MAYER, AND DAVID HARRISON BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * Table - Geometry Management Widget for the X Toolkit David Harrison UC Berkeley Electronics Research Lab (davidh@ic.Berkeley.EDU, ...!ucbvax!ucbcad!davidh) Table is a composite widget designed to manage the size and location of its children. The widget uses an array model to simplify the arrangement of child widgets. The widget is directly derived from the core and composite widgets provided by the X Toolkit and can be used with any widget set. It has been tested using the Athena widget set. Below is a short summary on the operation and use of the Table widget. It assumes a working knowledge of the X Toolkit Intrinsics. The Table widget addresses formatting for dialog boxes. Dialog boxes are rectangular windows that contain a wide variety of widgets. Most dialog boxes are arranged with widgets aligned in a way similar to the layout found in business forms. The Table widget is designed to make such layouts easy to specify. When designing dialog boxes that resemble business forms, the primary problem is specifying the alignment between widgets. The Table widget addresses this problem by adopting an array model. Under this model, widgets are placed at row and column locations in a variable sized array. Widgets may span more than one row or column. The array can expand or contract in size as needed. There are options to control justification and place size restrictions on rows and columns of widgets. The Table widget can contain any number and type of sub-widgets (including other Table widgets). XtCreateWidget() is used to create new Table widgets using the class variable tableWidgetClass. The resources listed below are retrieved from the argument list or from the resource database: tableWidgetClass Name Type Default Description -------------------------------------------------------------------------------- XmNbackground Pixel XtDefaultBackground Window background XmNborderColor Pixel XtDefaultForeground Window border XmNborderWidth Dimension 0 Width of border XmNx Position 0 X position of table XmNy Position 0 Y position of table XmNwidth Dimension (computed at realize) Width of form XmNheight Dimension (computed at realize) Height of form XmNmappedWhenManaged Boolean True XtMapWidget is automatic XmNsensitive Boolean True Widget receives input XmNlayout Layout None See text XmNmarginHeight Dimension 0 Int. horizontal padding XmNmarginWidth Dimension 0 Int. vertical padding XmNverticalSpacing Dimension 0 Inter-column padding XmNhorizontalSpacing Dimension 0 Inter-row padding XmNdefaultOptions Options None See text Widgets are added to a Table by specifying a Table widget as the parent widget when the widget is created. Once a widget is added to a table, it can be assigned a row and column position, a horizontal and vertical span, and justification options. This information can be specified in two ways: using public access functions or using the resource database. Public access functions allow the programmer to dynamically alter the formatting of children of a Table widget. One can alter the position, span, or options of a widget using XtTblConfig: void XtTblConfig( Widget w, /* Subwidget to modify */ Position col, /* Column position (horizontal) */ Position row, /* Row position (vertical) */ Dimension h_span, /* How many columns to span */ Dimension v_span, /* How many rows to span */ XtTblMask opt /* Justification options */ ); The specified widget (which must be a child of a Table widget) will be placed at column `col' and row `row'. The widget will span `h_span' columns to the right of `col' and `v_span' rows below `row'. The array for the table will expand as necessary. Options are specified by `or'ing together the following option bits: TBL_LEFT Horizontally left justified. TBL_RIGHT Horizontally right justified. TBL_TOP Vertically top justified. TBL_BOTTOM Vertically bottom justified. TBL_LK_WIDTH Don't try to expand the widget horizontally. TBL_LK_HEIGHT Don't try to expand the widget vertically. TBL_SM_WIDTH Force the width to be as small as possible. TBL_SM_HEIGHT Force the height to be as small as possible. Alternatively, if `options' is equal to TBL_DEF_OPT, the options are set to the default options for the Table widget. The default options for the Table widget are set using the XtNdefaultOptions resource (see resource specifications below). The routine changes the formatting information in its internal table. If the Table widget is realized, the positions of all child widgets are recomputed and the change on the screen will be immediate. The Table widget computes the size of a widget based on the minimum size required for the row(s) and column(s) it occupies. However, some widgets may require less space than that computed by the Table widget. In this case, the widget is aligned in the larger space according to the bits TBL_LEFT, TBL_RIGHT, TBL_TOP, and TBL_BOTTOM. These bits may be combined (i.e. TBL_RIGHT|TBL_TOP specifies upper right hand corner justification). If no justification bits are specified, the widget is centered. Some widgets may be amenable to growing to any size specified by the Table widget. Often, it may be desirable to force these widgets to remain at their optimal size for asthetic or operational convenience. If the TBL_LK_WIDTH bit is specified, the Table widget will not make the widget any wider than it's original desired size. Similarly, if the TBL_LK_HEIGHT bit is specified, the Table widget will not make the widget any taller than it's original size. Note this may bring widget justification into play. When a Table widget is resized, it automatically recomputes the sizes of the rows and columns of an array and distributes extra space evenly among the rows and columns. Often, it may be useful to control this distribution of space so that some rows or columns are not resized when extra space becomes available. If the TBL_SM_WIDTH bit is specified, the entire column(s) containing the widget are excluded from the excess space distribution algorithm. Thus, the column(s) are forced to remain as small as possible. The TBL_SM_HEIGHT bit works the same way with respect to the row(s) containing the widget. A title bar is a good example of this concept. When a dialog is resized, any excess vertical space should be given to the body of the dialog not to the title bar. Thus, TBL_SM_HEIGHT would be specified for a title bar widget. In most applications, the programmer will not set all of the above information for all widgets. The following convenience functions have been defined for use in these cases: void XtTblPosition( Widget w, /* Child of table widget */ Position col, /* Column position (horizontal) */ Position row /* Row position (vertical) */ ); The specified widget (which must be a child of a Table widget) will be placed at column `col' and row `row'. The vertical and horizontal span of the widget will remain unchanged. If the span of the widget was not set, it will default to one row and one column. The justification options of the widget will remain unchanged. If the justification options of the widget were not set, it will default to TBL_DEF_OPT (see XtTblConfig). void XtTblResize( Widget w, /* Child of table widget */ Dimension h_span, /* How many columns to span */ Dimention v_span /* How many rows to span */ ); This routine changes the span of widget `w' (which must be a child of a Table widget) to span `h_span' columns and `v_span' rows. Any previous position or options assigned to the widget will be preserved. If no position is associated with the widget, it will be placed at (0,0). If no options are associated with the widget, its options will be the defaults for the parent table widget. void XtTblOptions( Widget w, /* Child of table widget */ XtTblMask opt /* Option mask */ ); This routine changes the option bits of widget `w' (which must be a child of a Table widget) to `opt'. The options are as described for XtTblConfig(). Any associated position and span of the widget remains unchanged. If the widget hasn't been placed, it will be located at (0,0) and given a span of (1,1). Layout information may also be specified using XtSetValues() or using the resource database. The resources XtNlayout and XtNdefaultOptions may both be set in this fashion. The XtNlayout resource allows the user to specify the row, column, vertical span, horizontal span, and options for a set of widgets statically through the resource database or dynamically using XtSetValues(). The type of this resource is private to the Table widget. However, the widget automatically registers a type converter that converts between a string layout format and the internal form used by the Table widget. This form is a list of statements separated by semicolons. Each statement has the form: widget_name column row horizontal_span vertical_span opt_list widget_name Name of the widget as given to XtCreateWidget(). column Integer >= 0 giving column in array row Integer >= 0 giving row in array horizontal_span Integer >= 1 giving number of columns to span vertical_span Integer >= 1 giving number of rows to span opt_list Series of characters each representing an option: l: TBL_LEFT r: TBL_RIGHT t: TBL_TOP b: TBL_BOTTOM w: TBL_LK_WIDTH h: TBL_LK_HEIGHT W: TBL_SM_WIDTH H: TBL_SM_HEIGHT The options are as described for XtTblConfig(). The horizontal_span, vertical_span, and opt_list are optional and may be omitted. The horizontal and vertical spans will default to 1. The option list will default to the default options for the Table widget. A sample layout description is given below: "Title 0 0 2 1 H; First 0 1; Second 1 1" When using XtSetValues to specify the XtNlayout resource, the caller should use the following function to parse a textual form into the internal form used by the Table widget: caddr_t XtTblParseLayout( String layout /* String layout specification */ ); This function parses `layout' into an internal form that can be passed to a Table widget as the XtNlayout resource. The form of the layout is described above. Unless otherwise specified, all options for widgets created under a Table widget are set based on the default options for the Table widget. These default options are set using the XtNdefaultOptions resource. This resource can be specified in the resource database as a string of option characters. This string has the same form as the opt_list described above for XtTblParseLayout(). /* * Table Widget Example - Using resources * * Place the following entries in your resources file: * TableExample.table.Layout: title 0 0 2 1 H; bt1 0 1; bt2 1 1 * TableExample*title.label: Title Bar * TableExample*bt1.label: Button One * TableExample*bt2.label: Button Two */ #include #include #include #include #include #include "Table.h" #define MAX_ARGS 10 #define APP_NAME "TableExample" main(argc, argv) int argc; char *argv[]; { Widget initialize(), top, table, title, bt1, bt2; Arg arg_list[MAX_ARGS]; int arg_len; top = initialize(&argc, argv); arg_len = 0; table = XtCreateManagedWidget("table", tableWidgetClass, top, arg_list, arg_len); title = XtCreateManagedWidget("title", labelWidgetClass, table, arg_list, arg_len); bt1 = XtCreateManagedWidget("bt1", commandWidgetClass, table, arg_list, arg_len); bt2 = XtCreateManagedWidget("bt2", commandWidgetClass, table, arg_list, arg_len); XtRealizeWidget(top); XtMainLoop(); } Widget initialize(argc_p, argv) int *argc_p; char *argv[]; { Widget top; Display *disp; Arg arg_list[MAX_ARGS]; int arg_len; XtToolkitInitialize(); disp = XtOpenDisplay((XtAppContext) 0, "", argv[0], APP_NAME, (XrmOptionDescRec *) 0, 0, argc_p, argv); arg_len = 0; XtSetArg(arg_list[arg_len], XtNallowShellResize, True); arg_len++; top = XtAppCreateShell(argv[0], APP_NAME, applicationShellWidgetClass, disp, arg_list, arg_len); return top; } /* * Table Widget Example - Direct specification * * This program creates one button for each string on the command * line. Try "ex2 *" to see all the files in the directory. */ #include #include #include #include #include #include "Table.h" #define MAX_ARGS 10 #define APP_NAME "TableExample" #define NUM_ROWS 3 main(argc, argv) int argc; char *argv[]; { Widget initialize(), top, table, title, button; Arg arg_list[MAX_ARGS]; int arg_len, i, cols; top = initialize(&argc, argv); arg_len = 0; table = XtCreateManagedWidget("table", tableWidgetClass, top, arg_list, arg_len); XtSetArg(arg_list[arg_len], XtNlabel, "Title Bar"); arg_len++; title = XtCreateManagedWidget("title", labelWidgetClass, table, arg_list, arg_len); /* Each column will have three rows */ cols = (argc-1)/NUM_ROWS + 1; XtTblConfig(title, 0, 0, cols, 1, TBL_SM_HEIGHT); for (i = 1; i < argc; i++) { arg_len = 0; XtSetArg(arg_list[arg_len], XtNlabel, argv[i]); arg_len++; button = XtCreateManagedWidget("button", commandWidgetClass, table, arg_list, arg_len); if (i < argc-1) { XtTblPosition(button, (i-1)/NUM_ROWS, (i-1)%NUM_ROWS + 1); } else { /* Last one spans to bottom */ XtTblConfig(button, (i-1)/NUM_ROWS, (i-1)%NUM_ROWS + 1, 1, 3 - ((i-1)%NUM_ROWS), TBL_DEF_OPT); } } XtRealizeWidget(top); XtMainLoop(); } Widget initialize(argc_p, argv) int *argc_p; char *argv[]; { Widget top; Display *disp; Arg arg_list[MAX_ARGS]; int arg_len; XtToolkitInitialize(); disp = XtOpenDisplay((XtAppContext) 0, "", argv[0], APP_NAME, (XrmOptionDescRec *) 0, 0, argc_p, argv); arg_len = 0; XtSetArg(arg_list[arg_len], XtNallowShellResize, True); arg_len++; top = XtAppCreateShell(argv[0], APP_NAME, applicationShellWidgetClass, disp, arg_list, arg_len); return top; }