Upload
kevon-venables
View
252
Download
0
Tags:
Embed Size (px)
Citation preview
Container Widgets
Container widgets can be used to combine other widgets into composite panels. Examples:– XmMessageBox– XmForm– XmBulletinBoard– XmRowColumn– XmPanedWindow– XmFrame– XmMainWindow– XmScrolledWindow
An XmForm Widget
This widget collects four XmPushButton widgetsinto a form in which the relationships between thebutton widgets and the form are explicitly defined.
Creating Widgets for a Form
#include <Xm/Xm.h>#include <Xm/Form.h>#include <Xm/PushB.h>... // Create a form and four children Widget form, widgetA, widgetB, widgetC, widgetD; form = XtCreateManagedWidget ( "form",
xmFormWidgetClass,parent, NULL, 0);
widgetA = XtCreateManagedWidget ( "widgetA", xmPushButtonWidgetClass, form, NULL, 0 );
widgetB = XtCreateManagedWidget ( "widgetB", xmPushButtonWidgetClass, form, NULL, 0 );
widgetC = XtCreateManagedWidget ( "widgetC", xmPushButtonWidgetClass, form, NULL, 0 );
widgetD = XtCreateManagedWidget ( "widgetD", xmPushButtonWidgetClass, form, NULL, 0 );
Widget Relationships
At this point the parent-child relationships have beenestablished:
toplevel
form
widgetB widgetC widgetDwidgetA
However, their relationships within the form havenot been established.
Defining Form Relationships
widgetA
widgetB
widgetD
widgetC
Form
Note that if an attachment X Y is defined, Y Xmust not be, or you will have a circular constraint.
Relationships For widgetA
● Top attached to: form● Bottom attached to: form● Left attached to: form● Right attached to: none
Relationships For widgetB
● Top attached to: form● Bottom attached to: widgetC● Left attached to: widgetA● Right attached to: widgetD
Setting Attachment Resources
XtVaSetValues ( widgetA, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_NONE, NULL ); XtVaSetValues ( widgetB, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, widgetC, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, widgetA, XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, widgetD, NULL ); // continued . . .
Similarly for widgetC and widgetD.
Resizing Form Widgets
Here is the form widget as displayed by KDE:
Suppose the widgetis resized by pullingdown here.
Resizing Form Widgets (cont'd)
Result:
Form Widgets and the 8-Puzzle
Q: Is an XmForm widget the way to display an 8-puzzle?
A: Probably not, because the tiles would be attached to the form and to each other.
While it would be possible to change attachments in callbacks, it would probably be messy and error-prone.
A better container widget for tiles might be the XmBulletinBoard widget.
XmBulletinBoard Widgets
● The XmBulletinBoard widget is used when an application needs to explicitly control the position and sizes of a collection of widgets, and . . .
● . . . also when the application does not need to support resizable windows.
● Children of an XmBulletinBoard widget must be explicitly positioned by setting the XmNx and XmNy resources of each child.
An Empty XmBulletinBoard Widget
This is a 200 x 200 pixel bulletin board widget withno children.
Creating an Empty Bulletin Board
#include <Xm/Xm.h>#include <Xm/BulletinB.h>#include <Xm/Label.h>
... Widget bboard; bboard = XtVaCreateManagedWidget ( "bboard",
xmBulletinBoardWidgetClass, parent,
XmNwidth, 200, XmNheight, 200, NULL );
A BulletinBoard Widget with Children
This BulletinBoard widget contains three Labelchildren widgets placed in specific positions.
The upper left corner of the BulletinBoard isposition (x,y) = (0,0), which is the default positionof any child.
Adding Children to the Bulletin Board
Widget label1, label2, label3; label1 = XtVaCreateManagedWidget( "label1",
xmLabelWidgetClass, bboard, XmNlabelString, XmStringCreateLocalized("foo"), NULL );
label2 = XtVaCreateManagedWidget( "label2", xmLabelWidgetClass, bboard, XmNlabelString, XmStringCreateLocalized("bar"), XmNx, 75, XmNy, 75, NULL );
label3 = XtVaCreateManagedWidget( "label3", xmLabelWidgetClass, bboard, XmNlabelString, XmStringCreateLocalized("baz"), XmNx, 150, XmNy, 150, NULL );
Tic-Tac-Toe Example
● Suppose we want to modify the Tic-Tac-Toe game display so that:– A title TIC-TAC-TOE appears to the right of the grid– A HELP button appears beneath the title, and– Clicking on the HELP button displays a message box
describing the game and rules● We will accomplish this in stages:
– First, create a form widget and put the canvas (drawing area) and title label in it
BoardInfo Class
class BoardInfo {public: BoardInfo(Widget parent, Game g); void drawGrid(); // draw game grid void drawX ( Integer x, Integer y); // Draw an X at (x,y) void drawO ( Integer x, Integer y); // Draw an O at (x,y) void manage(); // expose the drawing area void unManage(); // hide the drawing area void asciiDisplay(); // display for debuggingprivate: DECL_CALLBACK(drawBoard); // draw board whenever it is exposed DECL_CALLBACK(boardClick); // get board coordinates when clicked Game game; // the game state Widget form; // Manager Widget title; // label for title Widget canvas; // drawing area Display* display; // display device for this app GC gc; // graphics context};
Adding A Label Widget in the BoardInfo Constructor
...form = XtCreateManagedWidget("form", xmFormWidgetClass, parent, NULL, 0);canvas = XtVaCreateManagedWidget ( "canvas", xmDrawingAreaWidgetClass, form, XmNsensitive, FALSE, // to start XmNheight, 300,
XmNwidth, 300, NULL );
XmString xmstr = XmStringCreateLocalized("TIC-TAC-TOE");title = XtVaCreateManagedWidget("title", xmLabelWidgetClass, form,
XmNlabelString, xmstr, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, canvas, XmNrightAttachment, XmATTACH_FORM, NULL); ...
New Display
Note: Larger font is achieved using the X ResourceManager (described later).
Presentation would be improved if the drawing areawere contained within a frame.
Modified BoardInfo Class
class BoardInfo {public: BoardInfo(Widget parent, Game g); void drawGrid(); // draw game grid void drawX ( Integer x, Integer y); // Draw an X at (x,y) void drawO ( Integer x, Integer y); // Draw an O at (x,y) void manage(); // expose the drawing area void unManage(); // hide the drawing area void asciiDisplay(); // display for debuggingprivate: DECL_CALLBACK(drawBoard); // draw board whenever it is exposed DECL_CALLBACK(boardClick); // get board coordinates when clicked Game game; // the game state Widget form; // Manager Widget title; // label for title Widget canvas; // drawing area Widget frame; // frame for drawing area Display* display; // display device for this app GC gc; // graphics context};
Using the Frame Widget Class
form = XtCreateManagedWidget("form", xmFormWidgetClass, parent, NULL, 0);frame = XtVaCreateManagedWidget( "frame", xmFrameWidgetClass, form,
XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_NONE, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_NONE, NULL);
canvas = XtVaCreateManagedWidget( "canvas", XmDrawingAreaWidgetClass, frame,
... );XmString xmstr = XmStringCreateLocalized("TIC-TAC-TOE");title = XtVaCreateManagedWidget( "title", xmLabelWidgetClass, form,
...);
New Display
Now we can add the HELP button to the form.
Modified BoardInfo Class
class BoardInfo {public: BoardInfo(Widget parent, Game g); void drawGrid(); // draw game grid void drawX ( Integer x, Integer y); // Draw an X at (x,y) void drawO ( Integer x, Integer y); // Draw an O at (x,y) void manage(); // expose the drawing area void unManage(); // hide the drawing area void asciiDisplay(); // display for debuggingprivate: DECL_CALLBACK(drawBoard); // draw board whenever it is exposed DECL_CALLBACK(boardClick); // get board coordinates when clicked Game game; // the game state Widget form; // Manager Widget title; // label for title Widget canvas; // drawing area Widget frame; // frame for drawing area Widget helpButton; Display* display; // display device for this app GC gc; // graphics context};
Adding A HELP Buttonform = XtCreateManagedWidget("form", xmFormWidgetClass, parent, NULL, 0);frame = XtVaCreateManagedWidget( "frame", xmFrameWidgetClass, form,
...);canvas = XtVaCreateManagedWidget( "canvas", XmDrawingAreaWidgetClass, frame,
... );XmString xmstr = XmStringCreateLocalized("TIC-TAC-TOE");title = XtVaCreateManagedWidget( "title", xmLabelWidgetClass, form,
...);xmstr = XmStringCreateLocalized("HELP");helpButton = XtVaCreateManagedWidget( "help", xmPushButtonWidgetClass, form,
XmNlabelString, xmstr, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, title, XmNleftAttachment, XmATTACH_WIDGET, XmNleftWidget, frame, NULL);
New Display
Note: Color was added using the X Resource Manager.
If the HELP button does not have a left or right attachment, it will not appear.
Implementing the HELP Button● Desired behavior:
– Pop up a message box containing a scrolled window of help text
– Allow user to dismiss window when not needed● This is the behavior of a dialog, but none of the
pre-defined dialogs contain scrolled windows● Approach:
– Use a pre-defined message dialog– Remove unnecessary children (icon and message)– Add a scrolled window as child– Shell and buttons are retained
Removing Children From A Container
● Use the convenience function:– XtUnmanageChild(<child>)
● To accesss the children of a dialog:– XmGetMessageBoxChild(<dialog>, <name>)– where <name> is one of:
● XmDIALOG_SYMBOL_LABEL● XmDIALOG_MESSAGE_LABEL● XmDIALOG_SEPARATOR● XmDIALOG_OK_BUTTON● XmDIALOG_CANCEL_BUTTON● XmDIALOG_HELP_BUTTON
Modified BoardInfo Class
class BoardInfo {public: BoardInfo(Widget parent, Game g); void drawGrid(); // draw game grid void drawX ( Integer x, Integer y); // Draw an X at (x,y) void drawO ( Integer x, Integer y); // Draw an O at (x,y) void manage(); // expose the drawing area void unManage(); // hide the drawing area void asciiDisplay(); // display for debuggingprivate: DECL_CALLBACK(drawBoard); // draw board whenever it is exposed DECL_CALLBACK(boardClick); // get board coordinates when clicked DECL_CALLBACK(help); // pop up help message box Game game; // the game state Widget form; // Manager Widget title; // label for title Widget canvas; // drawing area Widget frame; // frame for drawing area Widget helpButton; Widget helpDialog; // help message box Display* display; // display device for this app GC gc; // graphics context};
Customizing and Testing the Help Dialog in the BoardInfo
Constructor
...helpDialog = XmCreateMessageDialog(form, "helpDialog", NULL, 0);XtUnmanageChild(XmMessageBoxGetChild(helpDialog,
XmDIALOG_SYMBOL_LABEL));XtUnmanageChild(XmMessageBoxGetChild(helpDialog,
XmDIALOG_MESSAGE_LABEL));xmstr = XmStringCreateLocalized("This is a test help message");XtVaCreateManagedWidget( "helpTest", xmLabelWidgetClass, helpDialog,
XmNlabelString, xmstr, NULL);
XtAddCallback(helpButton, XmNactivateCallback, &BoardInfo::helpCallback, (XtPointer) this);
...
The (Simple) Help Button Callback and Behavior
IMPL_CALLBACK(BoardInfo, help){ XtManageChild(helpDialog);}
Text Widgets
● A realistic HELP message would contain multiple lines of text
● For this we can use the XmText widget class:– Functions as a complete text editor– Can be set to read-only with XmNeditable resource– Text to be displayed set with the XmNvalue resource– XmTextField is a subclass for more efficient
handling of one-line text fields
Using A Text Widget for Help
...String helpstr = "Here is a multi-line help message.It should be displayed within an XmText widget.If this were a long message it may need to be scrolled."; XtVaCreateManagedWidget( "helpTest", xmTextWidgetClass, helpDialog,
XmNvalue, helpstr, XmNresizeWidth, TRUE, // Without these, full XmNresizeHeight, TRUE, // message will not show XmNeditable, FALSE, // So contents cannot
// be changed NULL);
...
New Help Button Behavior