 |
DECwindows Motif Guide to Application
Programming
- Include the DXmSvn.h file.
- The bitmap data to use when creating the
pixmap. On OpenVMS systems, you can use the DECW$EXAMPLES:XBITMAP.EXE
program to create the bitmap.
- Declare data structures to be of type _Node
and initialize the first two fields of all of the data structures
needed to represent the data hierarchy. For example, for B, the
level field is initialized to 1, and the
number field is initialized to 7 to indicate that
there are 7 children at level 1.
- This example uses entries with two
components: a pixmap and text.
- Specify the svn.uid (UNIX) or SVN.UID
(OpenVMS) file.
- Fetch the SVN widget, manage it, and realize
the top-level widget.
Example 9-6 contains the SVN widget callbacks.
Example 9-6 SVN Callbacks |
.
.
.
/* Svn Attach Callback */
(1)static void svn_attach_proc(svnw)
Widget svnw;
{
/*
** Local data declarations
*/
unsigned int entry_tags [1];
/*
** Announce the routine on the debugging terminal
*/
printf ("AttachToSource handler\n");
/*
** Initialize the book data structure
*/
LclInitializeList ();
/*
** Make room for the books entries. I will pass the tag array here since I
** know that I have exactly one entry and it's easy to figure out the tag.
*/
entry_tags[0] = (unsigned int) &B;
DXmSvnAddEntries (svnw, 0, 1, 0, entry_tags, TRUE);
/*
** Reflect this addition in the global count.
*/
SourceNumEntries = 1;
}
/*
** SelectAndConfirm callback routine. This routine is called when one and
** only one Entry is selected. The Entry number selected is provided in the
** callback structure.
*/
(2)static void svn_confirm_proc(w, unused_tag, data)
Widget w;
int unused_tag;
DXmSvnCallbackStruct *data;
{
/*
** Announce the routine on the debugging terminal
*/
printf ("SelectAndConfirm handler\n");
/*
** Determine if the Entry can be expanded. If so, then tell the source module
** to deal with it.
*/
if (SourceIsNodeParent (data->entry_number, data->entry_tag) == TRUE)
{
SourceToggleNode (data->entry_number, data->entry_tag);
DXmSvnClearSelection (w, data->entry_number);
};
}
/*
** This routine is called when the widget wants the Source module to set
** the information associated with a particular entry.
*/
(3)static void svn_get_entry_proc(svnw, unused_tag, data)
Widget svnw;
int unused_tag;
DXmSvnCallbackStruct *data;
{
/*
** Local data declarations
*/
int i;
NodePtr node;
Arg args[10];
XmFontList fontlist;
fontlist = XmFontListCreate (XLoadQueryFont (XtDisplay(toplevel),
"*helvetica-medium-r-*-14-*"), XmSTRING_DEFAULT_CHARSET);
/*
** Announce the routine on the debugging terminal
*/
printf ("GetEntry handler - entry_number = %d, entry_tag = %d\n",
data->entry_number, data->entry_tag);
/*
** Get at the node (if needed)
*/
if (data->entry_tag == 0)
node = LclGetNodePtr (data->entry_number);
else node = (NodePtr) data->entry_tag;
/*
** Set up the pixmaps
*/
LclSetUpPixmap (svnw);
/*
** Set the entry information that both children and parent nodes
** have in common.
*/
DXmSvnSetEntryNumComponents (svnw, data->entry_number, SourceNumComps);
DXmSvnSetEntryTag (svnw, data->entry_number, node);
/*
* The first component is different in parent/child nodes and always present.
* If there are no children, use the child pixmap. Otherwise use the parent
* pixmap.
*/
if (node->number == 0)
DXmSvnSetComponentPixmap (svnw, data->entry_number, 1, 0, 0,
child_pixmap, pixmap_width, pixmap_height);
else DXmSvnSetComponentPixmap (svnw, data->entry_number, 1, 0, 0,
parent_pixmap, pixmap_width, pixmap_height);
(4)DXmSvnSetComponentText (svnw, data->entry_number, 2, pixmap_width+4,
0, node->text, fontlist);
}
/*
** Global routine that opens a closed node or closes an open node.
*/
void SourceToggleNode (node_number, entry_tag)
int node_number;
unsigned int entry_tag;
{
/*
** Local data declarations
*/
NodePtr node;
/*
** Get at the node (if needed)
*/
if (entry_tag == 0)
node = LclGetNodePtr (node_number);
else node = (NodePtr) entry_tag;
/*
** If it is opened, then close it. Otherwise open it.
*/
if (node->opened == TRUE)
SourceCloseNode (node_number, entry_tag);
else SourceOpenNode (node_number, entry_tag);
}
/*
** Global routine that tells the caller if the given node has child nodes.
*/
Boolean SourceIsNodeParent (node_number, entry_tag)
int node_number;
unsigned int entry_tag;
{
/*
** Local data declarations
*/
NodePtr node;
/*
** Get at the node (if needed)
*/
if (entry_tag == 0)
node = LclGetNodePtr (node_number);
else node = (NodePtr) entry_tag;
/*
** Return TRUE or FALSE
*/
if (node->children == 0)
return FALSE;
else return TRUE;
}
/*
** Global routine that opens a node, given the node number
*/
static void SourceOpenNode(node_number, entry_tag)
int node_number;
unsigned int entry_tag;
{
/*
** Local data declarations
*/
NodePtr node;
NodePtr child_node;
int i, x, y;
/*
** Get at the node (if needed)
*/
if (entry_tag == 0)
node = LclGetNodePtr (node_number);
else node = (NodePtr) entry_tag;
/*
** If it is already opened, then return.
*/
if (node->opened == TRUE)
return;
/*
** If it has no children, then return.
*/
if (node->number == 0)
return;
/*
** Mark the node as being opened
*/
node->opened = TRUE;
/*
* Add the entries. This code does not yet use the entry_tags array.
*/
DXmSvnAddEntries (svn_widget, node_number, node->number,
node->level, NULL, FALSE);
/*
* Get to the first child of this node
*/
child_node = node->children;
/*
* For each child, call SetEntry if the child has children. Also set their
* positions in case we have a UserDefined Tree Style.
*/
DXmSvnGetEntryPosition(svn_widget, node_number, FALSE, &x, &y);
for (i = 1; i <= node->number; i++)
{
if (child_node->children != 0)
DXmSvnSetEntry (svn_widget, node_number+i, 0, 0, 2, 1, 0, FALSE);
child_node = child_node->sibling;
x += 30;
y += 30;
DXmSvnSetEntryPosition(svn_widget, node_number+i, FALSE, x, y);
};
/*
** Reflect this addition in the global count.
*/
SourceNumEntries = SourceNumEntries + node->number;
}
/*
** Global routine that closes a node, given the node number
*/
void SourceCloseNode (node_number, entry_tag)
int node_number;
unsigned int entry_tag;
{
/*
** Local data declarations
*/
NodePtr node;
/*
** Get at the node (if needed)
*/
if (entry_tag == 0)
node = LclGetNodePtr (node_number);
else node = (NodePtr) entry_tag;
/*
** Call the local recursive close routine.
*/
LclCloseNode(node, node_number);
}
/*
** Recursively close all nodes given a current node pointer
** and a current node number.
*/
void LclCloseNode(node, node_number)
NodePtr node;
int node_number;
{
/*
** Local data declarations
*/
int i;
NodePtr child_node;
/*
** If the current node is not opened, then return
*/
if (node->opened == FALSE)
return;
/*
** Get to the first child of this node
*/
child_node = node->children;
/*
** For each child, call CloseNode on each child
*/
for (i=1; i<=node->number; i++)
{
LclCloseNode (child_node, node_number);
child_node = child_node->sibling;
};
/*
** Tell SVN to remove its children
*/
DXmSvnDeleteEntries (svn_widget, node_number, node->number);
/*
** Mark the node closed
*/
node->opened = FALSE;
if (node->stext != NULL) XtUnmanageChild(node->stext);
/*
** Reflect this removal in the global count.
*/
SourceNumEntries = SourceNumEntries - node->number;
}
/*
** Routine that maps a node_number into a node structure pointer.
*/
NodePtr LclGetNodePtr (node_number)
int node_number;
{
/*
** Local routine data
*/
int i;
NodePtr current_node = &B;
/*
** Loop through until it's found. If we hit the end of the list, then
** we'll return a null pointer.
*/
if (node_number != 1)
for (i = 2; i <= node_number; i++)
if (current_node == NULL)
break;
else if (current_node->opened)
current_node = current_node->children;
else current_node = current_node->sibling;
/*
** Return the node address
*/
return current_node;
}
.
.
.
|
- After you create an instance of the SVN
widget, you must attach it to the data for the hierarchy. The
attachment is done in the DXmSvnNattachToSourceCallback callback
routine, which is invoked when the SVN widget is realized.
- The user has double clicked on a single
entry. Your application is responsible for linking the data in the
hierarchy to entries in the SVN widget. The entry selected can be
determined by examining the entry_number and
entry_tag fields of the callback data structure.
- Once the data is attached to the SVN widget,
the SVN widget triggers the DXmSvnNgetEntryCallback to get information
associated with the first entry, such as the number of components and
the text from the data hierarchy to associate with the entry. Note that
DXmSvnNgetEntryCallback is triggered to get information about any entry
in the hierarchy, not just the first entry.
In the case of the SVN
demo application, the DXmSvnNgetEntryCallback callback routine performs
the following functions:
- Determines the font to use for the entry text.
- Associates the entry_number field of the callback
data structure with an entry in the data hierarchy.
- Chooses the icon to use with the entry. If there are no children,
the child pixmap is used. Otherwise the parent pixmap is used.
- Calls the DXmSvnSetEntryNumComponents routine to set the number of
components for this entry. The entries in the SVN demo application have
two components: the icon to use and the text associated with the entry.
- Calls the DXmSvnSetEntryTag routine to set the entry_tag field of
this entry to the address of the associated _Node data structure.
- Set the text associated with each entry.
Example 9-7 contains additional hierarchy data.
Example 9-7 SVN Hierarchy Data |
.
.
.
void LclInitializeList ()
{
B.text = XmStringCreate("OSF/Motif Style Guide V1.1", XmSTRING_DEFAULT_CHARSET);
P1.text = XmStringCreate("1. User Interface Design Principles", XmSTRING_DEFAULT_CHARSET);
P2.text = XmStringCreate("2. Input and Navigation Models", XmSTRING_DEFAULT_CHARSET);
P3.text = XmStringCreate("3. Selection and Component Activation", XmSTRING_DEFAULT_CHARSET);
P4.text = XmStringCreate("4. Application Design Principles", XmSTRING_DEFAULT_CHARSET);
P5.text = XmStringCreate("5. Window Manager Design Principles", XmSTRING_DEFAULT_CHARSET);
P6.text = XmStringCreate("6. Designing for International Markets", XmSTRING_DEFAULT_CHARSET);
P7.text = XmStringCreate("7. Controls, Groups, and Models Reference Pages",
XmSTRING_DEFAULT_CHARSET);
C11 .text = XmStringCreate("1.1 Adopt the User's Perspective", XmSTRING_DEFAULT_CHARSET);
C12 .text = XmStringCreate("1.2 Give the User Control", XmSTRING_DEFAULT_CHARSET);
C13 .text = XmStringCreate("1.3 User Real-World Metaphors", XmSTRING_DEFAULT_CHARSET);
C14 .text = XmStringCreate("1.4 Keep Interfaces Natural", XmSTRING_DEFAULT_CHARSET);
C15 .text = XmStringCreate("1.5. Keep Interfaces Consistent", XmSTRING_DEFAULT_CHARSET);
C16 .text = XmStringCreate("1.6 Communicate Application Actions to the User",
XmSTRING_DEFAULT_CHARSET);
C17 .text = XmStringCreate("1.7 Avoid Common Design Pitfalls", XmSTRING_DEFAULT_CHARSET);
C21 .text = XmStringCreate("2.1 The Keyboard Focus Model", XmSTRING_DEFAULT_CHARSET);
C22 .text = XmStringCreate("2.2 The Input Device Model", XmSTRING_DEFAULT_CHARSET);
C23.text = XmStringCreate("2.3 The Navigation Model", XmSTRING_DEFAULT_CHARSET);
C31.text = XmStringCreate("3.1 Selection Models", XmSTRING_DEFAULT_CHARSET);
C32.text = XmStringCreate("3.2 Selection Actions", XmSTRING_DEFAULT_CHARSET);
C33.text = XmStringCreate("3.3 Component Activation", XmSTRING_DEFAULT_CHARSET);
C41.text = XmStringCreate("4.1 Choosing Components", XmSTRING_DEFAULT_CHARSET);
C42.text = XmStringCreate("4.2 Layout", XmSTRING_DEFAULT_CHARSET);
C43.text = XmStringCreate("4.3 Interaction", XmSTRING_DEFAULT_CHARSET);
C44.text = XmStringCreate("4.4 Component Design", XmSTRING_DEFAULT_CHARSET);
C51.text = XmStringCreate("5.1 Configurability", XmSTRING_DEFAULT_CHARSET);
C52.text = XmStringCreate("5.2 Window Support", XmSTRING_DEFAULT_CHARSET);
C53.text = XmStringCreate("5.3 Window Decorations", XmSTRING_DEFAULT_CHARSET);
C54.text = XmStringCreate("5.4 Window Navigation", XmSTRING_DEFAULT_CHARSET);
C55.text = XmStringCreate("5.5 Icons", XmSTRING_DEFAULT_CHARSET);
C61.text = XmStringCreate("6.1 Collating Sequences", XmSTRING_DEFAULT_CHARSET);
.
.
.
/*
** Fill in the child pointers for the book, parts, and chapters
*/
B.children = &P1;
P1.children = &C11;
P2.children = &C21;
P3.children = &C31;
P4.children = &C41;
P5.children = &C51;
P6.children = &C61;
P7.children = NULL;
C11.children = NULL;
C12.children = &C121;
C13.children = &C131;
C14.children = &C141;
C15.children = NULL;
C16.children = &C161;
C17.children = NULL;
C21.children = &C211;
C22.children = &C221;
C23.children = &C231;
C31.children = &C311;
C32.children = &C321;
C33.children = &C331;
C41.children = &C411;
C42.children = &C421;
C43.children = &C431;
C44.children = NULL;
C51.children = NULL;
C52.children = &C521;
C53.children = &C531;
C54.children = NULL;
C55.children = &C551;
C61.children = NULL;
C62.children = &C621;
C63.children = NULL;
C64.children = NULL;
C65.children = NULL;
C66.children = NULL;
/*
** Fill in the sibling pointers for the book
*/
B.sibling = NULL;
/*
** Fill in the sibling pointers for the parts
*/
P1.sibling = &P2;
P2.sibling = &P3;
P3.sibling = &P4;
P4.sibling = &P5;
P5.sibling = &P6;
P6.sibling = &P7;
P7.sibling = NULL;
/*
** Fill in the sibling pointers for the chapters
*/
C11.sibling = &C12;
C12.sibling = &C13;
C13.sibling = &C14;
C14.sibling = &C15;
C15.sibling = &C16;
C16.sibling = &C17;
C17.sibling = &P2;
C21.sibling = &C22;
C22.sibling = &C23;
C23.sibling = &P3;
C31.sibling = &C32;
C32.sibling = &C33;
C33.sibling = &P4;
C41.sibling = &C42;
C42.sibling = &C43;
C43.sibling = &C44;
C44.sibling = &P5;
C51.sibling = &C52;
C52.sibling = &C53;
C53.sibling = &C54;
C54.sibling = &C55;
C55.sibling = &P6;
C61.sibling = &C62;
C62.sibling = &C63;
C63.sibling = &C64;
C64.sibling = &C65;
C65.sibling = &C66;
C66.sibling = &P7;
/*
** Fill in the sibling pointers for the sections of chapter 1
*/
C121.sibling = &C122;
C122.sibling = &C13;
C131.sibling = &C132;
C132.sibling = &C133;
C133.sibling = &C14;
C141.sibling = &C142;
C142.sibling = &C15;
C161.sibling = &C162;
C162.sibling = &C163;
C163.sibling = &C17;
/*
** Fill in the sibling pointers for the sections of chapter 2
*/
C211.sibling = &C212;
C212.sibling = &C22;
C221.sibling = &C222;
C222.sibling = &C223;
C223.sibling = &C23;
C231.sibling = &C232;
C232.sibling = &C233;
C233.sibling = &C234;
C234.sibling = &P3;
.
.
.
}
|
Example 9-8 creates the pixmaps used as icons.
Example 9-8 Creating the SVN Pixmaps
(Icons) |
.
.
.
void LclSetUpPixmap (svnw)
Widget svnw;
{
/*
** Local data declarations
*/
Screen *screen = XtScreen(toplevel);
Display *display = DisplayOfScreen (screen);
Pixel background_pixel;
Pixel foreground_pixel;
Arg args [2];
/*
** If we've already done this, then return.
*/
if (parent_pixmap != NULL) return;
/*
** Get the foreground/background colors of Svn
*/
XtSetArg (args[0], XmNforeground, &foreground_pixel);
XtSetArg (args[1], XmNbackground, &background_pixel);
XtGetValues (svnw, args, 2);
/*
** Create the pixmap.
*/
parent_pixmap = XCreatePixmapFromBitmapData (
display, /* (IN) display */
XDefaultRootWindow(display), /* (IN) drawable */
parent_pixmap_bits, /* (IN) bitmap data */
pixmap_width, /* (IN) width */
pixmap_height, /* (IN) height */
foreground_pixel, /* (IN) foreground pixel */
background_pixel, /* (IN) background pixel */
DefaultDepthOfScreen(screen)); /* (IN) pixmap depth */
child_pixmap = XCreatePixmapFromBitmapData (
display, /* (IN) display */
XDefaultRootWindow(display), /* (IN) drawable */
child_pixmap_bits, /* (IN) bitmap data */
pixmap_width, /* (IN) width */
pixmap_height, /* (IN) height */
foreground_pixel, /* (IN) foreground pixel */
background_pixel, /* (IN) background pixel */
DefaultDepthOfScreen(screen)); /* (IN) pixmap depth */
}
.
.
.
|
|