DECwindows Motif Guide to Application Programming


Previous Contents Index

  1. If the components are centered, pass a Boolean value of FALSE to revert to normal components. Switch the toggle-to label to "Components Centered".
  2. If the components are not centered, pass a Boolean value of TRUE to center the components. Switch the toggle-to label to "Normal Components".

9.3.4 Tree-Mode Outlines

You can use the DXmSvnNtreeEntryOutlines resource to toggle on and off the outline surrounding tree-mode entries.

For example, the SVN demo application sets the DXmSvnNtreeEntryOutlines resource to allow users to turn outlines on and off.


(1)if (outlines) 
     { 
        outlines = FALSE; 
        XtSetArg    (arguments[0], DXmSvnNtreeEntryOutlines, outlines); 
        XtSetValues (Svn, arguments, 1); 
        cs = XmStringCreate("Add Outlines", XmSTRING_DEFAULT_CHARSET); 
     } 
(2)else {  
        outlines = TRUE; 
        XtSetArg    (arguments[0], DXmSvnNtreeEntryOutlines, outlines); 
        XtSetValues (Svn, arguments, 1); 
        cs = XmStringCreate("Remove Outlines", XmSTRING_DEFAULT_CHARSET); 
     }; 

  1. If outlines are on, pass a Boolean value of FALSE to turn them off. Switch the toggle-to label to "Add Outlines".
  2. If outlines are off, pass a Boolean value of TRUE to turn them on. Switch the toggle-to label to "Remove Outlines".

9.3.5 Tree-Mode Entry Shadows

You can use the DXmSvnNtreeEntryShadows resource to add shadowing to the outline surrounding tree-mode entries.

For example, the SVN demo application sets the DXmSvnNtreeEntryShadows resource to allow users to turn shadowing on and off.


(1)if (shadows) 
    { 
        shadows = FALSE; 
        XtSetArg    (arguments[0], DXmSvnNtreeEntryShadows, shadows); 
        XtSetValues (Svn, arguments, 1); 
        cs = XmStringCreate("Add Shadows", XmSTRING_DEFAULT_CHARSET); 
     } 
(2)else { 
        shadows = TRUE; 
        XtSetArg    (arguments[0], DXmSvnNtreeEntryShadows, shadows); 
        XtSetValues (Svn, arguments, 1); 
        cs = XmStringCreate("Remove Shadows", XmSTRING_DEFAULT_CHARSET); 
     }; 

  1. If shadowing is on, pass a Boolean value of FALSE to turn it off. Switch the toggle-to label to "Add Shadows".
  2. If shadowing is off, pass a Boolean value of TRUE to turn it on. Switch the toggle-to label to "Remove Shadows".

9.3.6 Tree-Mode Perpendicular Lines

You can set the DXmSvnNtreePerpendicularLines resource to toggle between perpendicular and diagonal connecting lines for tree-mode entries.

For example, the SVN demo application sets the DXmSvnNtreePerpendicularLines resource to allow users to toggle between perpendicular and diagonal connecting lines.


(1) if (perpendicular_lines) 
        {                                          
           perpendicular_lines = FALSE; 
           XtSetArg (arguments[0], DXmSvnNtreePerpendicularLines, perpendicular_lines); 
           XtSetValues (Svn, arguments, 1); 
           cs = XmStringCreate("Perpendicular Lines", XmSTRING_DEFAULT_CHARSET); 
        } 
(2) else { 
           perpendicular_lines = TRUE; 
           XtSetArg (arguments[0], DXmSvnNtreePerpendicularLines, perpendicular_lines); 
           XtSetValues (Svn, arguments, 1); 
           cs = XmStringCreate("Diagonal Lines", XmSTRING_DEFAULT_CHARSET); 
        }; 

  1. If perpendicular lines are on, pass a Boolean value of FALSE to turn them off. Switch the toggle-to label to "Perpendicular Lines".
  2. If perpendicular lines are off, pass a Boolean value of TRUE to turn them on. Switch the toggle-to label to "Diagonal Lines".

9.4 Associating Callbacks with an SVN Widget

The SVN widget communicates with your application through callback routines established by the application during the creation of the widget. The SVN widget uses these callback routines when attaching to or detaching from the hierarchy data, as the result of a user action, when the widget needs the display information associated with an entry, and so forth.

The format of the DXmSvnCallbackStruct data structure is shown in Example 9-2.

Note

The format of the SVN callback data structure is specific to the callback. The only portion that is always available is the callback reason code.

Example 9-2 The DXmSvnCallbackStruct Data Structure

typedef struct 
{                
    int           reason;                                 
    int           entry_number; 
    int           component_number; 
    int           first_selection; 
    int           x; 
    int           y; 
    unsigned int  entry_tag; 
    Time          time;     
    int           entry_level; 
    int           loc_cursor_entry_number; 
    int           transfer_mode; 
    int           dragged_entry_number; 
    XEvent        *event;  
} DXmSvnCallbackStruct;  

To associate a callback routine with an SVN widget callback, pass a callback routine list to one of the SVN widget callback resources. See DECwindows Extensions to Motif for a list of the callbacks and the conditions that trigger them.

9.5 SVN Help Callback

Your application can use the DXmSvnNhelpRequestedCallback callback to specify a routine to call when the user requests help.

The SVN widget supports two mechanisms for generating help: pressing the Help key and requesting context-sensitive help on the scroll bar, navigation push button, or navigation window. The SVN widget sets one of two fields in the DXmSvnCallbackStruct data structure, depending on how help was requested:

Your help callback routine should check these two fields to determine the type of help the user requested.

Example 9-3 first tests the entry_number field to see if context-sensitive help was requested. If entry_number does not contain a negative number, the code tests the loc_cursor_entry_number field to make sure it is not NULL and then provides overview help on the SVN entries.

See Chapter 5 for information on using the DECwindows Help System routines.

Example 9-3 The SVN Help Callback

static void svn_help_proc (svnw, unused_tag, data) 
      Widget               svnw; 
      int                  unused_tag; 
      DXmSvnCallbackStruct *data; 
{ 
      int                  help_num = NULL; 
      int                  sens_num = NULL; 
                 
 
      help_num = data->loc_cursor_entry_number; 
      sens_num = data->entry_number;  
   
       if (sens_num < 0) {    
 
            if (sens_num == DXmSvnKhelpScroll) 
                 DXmHelpSystemDisplay(help_context, svn_help, 
                        "topic", "scroll", help_error, "Help System Error"); 
 
              else if (sens_num == DXmSvnKhelpNavButton ) 
                   DXmHelpSystemDisplay(help_context, svn_help, "topic", 
                           "navigate", help_error, "Help System Error"); 
 
                       else  
                           DXmHelpSystemDisplay(help_context, svn_help, 
                                                "topic", "overview", 
                                                help_error, 
                                                "Help System Error"); 
            return; 
       }; 
 
 
         if (help_num != NULL) { 
                    DXmHelpSystemDisplay(help_context, svn_help, "topic", 
                            "overview",  help_error, "Help System Error");    
        }; 
}                    

9.5.1 User-Generated Callbacks

There are a limited number of actions that a user can make during the lifetime of an SVN widget. Table 9-2 describes the callbacks that are generated as a result of user actions.

Table 9-2 User-Generated Callbacks
Action Callback Description
MB1 Click DXmSvnNentrySelectedCallback
DXmSvnNentryUnselectedCallback
DXmSvnNtransitionsDoneCallback
Selects one entry. The SVN widget sets all previously selected entries as unselected. Then it sets this entry as selected. The selected entry is displayed with reverse video.
MB1 Double Click DXmSvnNselectAndConfirmCallback The user has double clicked on a single entry. The callback indicates that the user wants to expand (or contract) this entry. The DXmSvnNselectAndConfirm callback routine opens the entry if it is not already opened and calls the DXmSvnAddEntry routine to add any children that the element might have.
MB1 Drag Click DXmSvnNentrySelectedCallback
DXmSvnNtransitionsDoneCallback
Entries are selected as they are passed over so that at each point all the entries from the press point to the current point are selected. Any entries selected when MB1 is clicked are unselected.
Shift/MB1 Click on an Entry DXmSvnNentrySelectedCallback
DXmSvnNtransitionsDoneCallback
All entries between the last selected entry (on MB1 Click) and the current entry that the Shift/MB1 Click is performed on become selected.
MB1/Ctrl Click DXmSvnNentrySelectedCallback
DXmSvnNentryUnselectedCallback
DXmSvnNtransitionsDoneCallback
The current entry's selection state is toggled. The location cursor moves to that entry.
MB1/Ctrl Drag DXmSvnNentrySelectedCallback
DXmSvnNentryUnselectedCallback
DXmSvnNtransitionsDoneCallback
Entries selection state are toggled as they are passed over so that all the entries from the press point to the current point are toggled.
MB2 Click DXmSvnNentryTransfer The DXmSvnNentryTransfer callback is generated with the transfer mode "Unknown" specified.
MB2/Ctrl Click DXmSvnNentryTransfer Same as MB2 Click, but the transfer of entry should be a copy operation implemented by the application. The DXmSvnKtransferCopy value is returned in the transfer_mode field of the callback data structure.
MB2/Alt Click DXmSvnNentryTransfer Same as MB2 Click, but the transfer of entry should be a move operation implemented by the application. The DXmSvnKtransferMove value is returned in the transfer_mode field of the callback data structure.
MB2 Drag DXmSvnNselectionsDragged If MB2 is clicked on a selected entry, all selected entries are dragged. If MB2 is clicked on a unselected entry, only that entry is dragged. A ghost of the entries is created and is dragged with the mouse to the release point. The DXmSvnNselectionsDragged callback is returned to the application. The transfer mode of "Unknown" is specified in the callback structure.
MB2/Ctrl Drag DXmSvnNselectionsDragged Same as MB2 Drag, but the transfer of entry or entries should be a copy operation implemented by the application. The DXmSvnKtransferCopy value is returned in the transfer_mode field of the callback data structure.
MB2/Alt Drag DXmSvnNselectionsDragged Same as MB2 Click, but the transfer of entry should be a move operation implemented by the application. The DXmSvnKtransferMove value is returned in the transfer_mode field of the callback data structure.
MB3 Click DXmSvnNpopupMenuCallback Pop-up menu callback to the application. The application should use this button only to implement a pop-up menu.

9.6 Creating an SVN Widget

Your application can use any of the methods described in Table 9-3 to create an instance of the SVN widget.

Table 9-3 SVN Widget Creation Routines
UIL object type Use the DXmSvn object-type identifier to create an SVN widget in a UIL module.
Toolkit routine Use the DXmCreateSvn routine to create an SVN widget.

Once the SVN widget is created, applications communicate with the widget through Toolkit routine calls. These routines can change the scope of the structure being displayed, inquire about selections, and manipulate those selections. Routines to manipulate the selections include clearing the selections, selecting all of the entries, and getting a list of selected entries.

At a minimum, your application must implement the following SVN callbacks:

  1. DXmSvnNattachToSourceCallback, as described in Section 9.2.1.1
  2. DXmSvnNgetEntryCallback, as described in Section 9.2.1.3
  3. DXmSvnNselectAndConfirmCallback, as described in Section 9.2.1.4

9.7 SVN Demo Application

This section describes a minimal implementation of the SVN demo application located in the /usr/examples/motif directory on Digital UNIX systems and the DECW$EXAMPLES directory on OpenVMS systems. This implementation uses the DXmSvn object-type identifier to create an SVN widget in a UIL module. (Note that the SVN demo application is not available with eXcursion for Windows NT.)

You can use this example as a starting point when adding the SVN widget to your application. See the SVN demo application for additional SVN features.

Note

The source code contains many comment lines that explain how the code functions. This example calls out lines of code that are of particular interest and provides additional information.

Example 9-4 contains the UIL module.

Example 9-4 svn.uil (UNIX) or SVN.UIL (OpenVMS) Module

   .
   .
   .
module form 
    version = 'v1.0' 
    names = case_sensitive 
 
procedure 
        svn_attach_proc    (); 
        svn_confirm_proc   (); 
        svn_get_entry_proc (); 
        exit_proc         (string);       
 
 
 
value 
        k_exit_accelerator              : "Ctrl<Key>z:"; 
        k_exit_accelerator_text         : "Ctrl/Z"; 
 
 
!Build menu for exit button 
 
 
object 
    S_MAIN_WINDOW : XmMainWindow { 
        arguments {                     
            XmNx = 0; 
            XmNy = 0; 
            XmNwidth = 800; 
            XmNheight = 800;                
         }; 
        controls {                      ! S_MAIN_WINDOW has two children. 
            XmMenuBar       s_menu_bar; 
            DXmSvn          main_svn; 
            }; 
        };    
 
object 
    s_menu_bar : XmMenuBar { 
        arguments {                     
            XmNorientation      = XmHORIZONTAL; 
            }; 
        controls {                              
            XmCascadeButton     file_menu_entry; 
            }; 
        }; 
 
object 
    file_menu_entry : XmCascadeButton { 
        arguments { 
            XmNlabelString      = "File"; 
            XmNmnemonic         = keysym("F"); 
            };                                            
 
        controls { 
            XmPulldownMenu      file_menu; 
            }; 
        }; 
 
 
! The file pull-down menu with the push buttons it controls. 
 
object 
    file_menu : XmPulldownMenu { 
        controls { 
            XmPushButton        exit_button; 
            }; 
        };         
 
object 
    exit_button : XmPushButton { 
        arguments { 
            XmNlabelString      = "Exit" ;                            
            XmNaccelerator      = k_exit_accelerator; 
            XmNacceleratorText  = k_exit_accelerator_text; 
            XmNmnemonic         = keysym("E"); 
            }; 
 
        callbacks { 
            XmNactivateCallback = procedure exit_proc('normal demo exit'); 
            }; 
        };           
 
 
 
!The SVN widget object 
 
  (1)object main_svn : DXmSvn 
            { 
            arguments            
                { 
                XmNwidth = 826; 
                XmNheight = 237;                
                };      
 
            callbacks                
                { 
                 DXmSvnNattachToSourceCallback = procedure svn_attach_proc(); 
                 DXmSvnNselectAndConfirmCallback = procedure svn_confirm_proc(); 
                 DXmSvnNgetEntryCallback = procedure svn_get_entry_proc(); 
                };                            
           };                                             
 
 
end module; 
   .
   .
   .

  1. Create an instance of the SVN widget with the three required callbacks: DXmSvnNattachToSourceCallback, DXmSvnNselectAndConfirmCallback, and DXmSvnNgetEntryCallback.

Example 9-5 contains the main part of the C program.

Example 9-5 svn.c (UNIX) or SVN.C (OpenVMS) Module

   .
   .
   .
#include <stdio> 
#include <Mrm/MrmAppl.h>      
(1)#include <DXm/DXmSvn.h>      
                      
    
Widget toplevel, main_widget, svn_widget; 
 
 
 
/******************************************************/ 
/*  Local declarations needed for SVN definitions  */ 
/******************************************************/ 
 
/* 
**  My local hierarchy storage structure 
*/ 
    typedef struct node  
        { 
          int             level;      /* level number of children    */ 
          int             number;     /* number of children          */ 
          XmString        text;       /* entry text                  */ 
          struct node    *sibling;    /* pointer to sibling or NULL  */ 
          struct node    *children;   /* pointer to children or NULL */ 
          Widget          stext;      /* stext widget for this entry */ 
          Boolean         opened;     /* children are showing        */ 
        }_Node, *NodePtr; 
 
 
/* 
**  Declarations used in building the pixmap 
*/ 
#define pixmap_width 13 
#define pixmap_height 13 
(2)static char parent_pixmap_bits[] = { 
   0x40, 0x00, 0xe0, 0x00, 0xf0, 0x01, 0x08, 0x02, 0xf4, 0x05, 0x16, 0x0d, 
   0x57, 0x1d, 0x16, 0x0d, 0xf4, 0x05, 0x08, 0x02, 0xf0, 0x01, 0xe0, 0x00, 
   0x40, 0x00}; 
 
static char child_pixmap_bits[] = { 
   0x40, 0x00, 0xa0, 0x00, 0x10, 0x01, 0x08, 0x02, 0x04, 0x04, 0x02, 0x08, 
   0x41, 0x10, 0x02, 0x08, 0x04, 0x04, 0x08, 0x02, 0x10, 0x01, 0xa0, 0x00, 
   0x40, 0x00}; 
                         
/* 
**  Pixmap structures 
*/ 
    static Pixmap parent_pixmap = NULL; 
    static Pixmap child_pixmap = NULL; 
    
 
 
 
/* 
**  Local data defining all of the nodes of the book.  We will initialize 
**  the first three fields of the structures, namely level, number, and 
**  text.  All of the remaining fields will be initialized in the local 
**  initialization routines. 
*/ 
 
    (3)static _Node B  = { 1, 7}; 
     
    static _Node P1 = { 2, 7}; 
    static _Node P2 = { 2, 3}; 
    static _Node P3 = { 2, 3}; 
    static _Node P4 = { 2, 4}; 
    static _Node P5 = { 2, 5}; 
    static _Node P6 = { 2, 6}; 
    static _Node P7 = { 2, 0}; 
 
    static _Node C11  = { 3, 0}; 
    static _Node C12  = { 3, 2}; 
    static _Node C13  = { 3, 3}; 
    static _Node C14  = { 3, 2}; 
    static _Node C15  = { 3, 0}; 
    static _Node C16  = { 3, 3}; 
    static _Node C17  = { 3, 0}; 
    static _Node C21  = { 3, 2}; 
    static _Node C22  = { 3, 3}; 
    static _Node C23 = { 3, 4}; 
    static _Node C31 = { 3, 9}; 
    static _Node C32  = { 3, 4}; 
    static _Node C33 = { 3, 7}; 
    static _Node C41 = { 3, 2}; 
    static _Node C42 = { 3, 4}; 
    static _Node C43 = { 3, 3}; 
    static _Node C44 = { 3, 0}; 
    static _Node C51 = { 3, 0}; 
    static _Node C52 = { 3, 3}; 
    static _Node C53 = { 3, 7}; 
    static _Node C54 = { 3, 0}; 
    static _Node C55 = { 3, 3}; 
    static _Node C61 = { 3, 0}; 
    static _Node C62 = { 3, 9}; 
    static _Node C63 = { 3, 0}; 
    static _Node C64 = { 3, 0}; 
    static _Node C65 = { 3, 0}; 
    static _Node C66 = { 3, 0}; 
    static _Node C70 = { 3, 0}; 
 
    
    static _Node C121 = { 4, 0}; 
    static _Node C122 = { 4, 0}; 
 
    static _Node C131 = { 4, 0}; 
    static _Node C132 = { 4, 0}; 
    static _Node C133 = { 4, 0}; 
 
    static _Node C141 = { 4, 0}; 
    static _Node C142 = { 4, 0}; 
 
    static _Node C161 = { 4, 0}; 
    static _Node C162 = { 4, 0}; 
    static _Node C163 = { 4, 0}; 
 
    static _Node C211 = { 4, 0}; 
    static _Node C212 = { 4, 0}; 
 
    static _Node C221 = { 4, 0}; 
    static _Node C222 = { 4, 0}; 
    static _Node C223 = { 4, 0}; 
 
    static _Node C231 = { 4, 0}; 
    static _Node C232 = { 4, 0}; 
    static _Node C233 = { 4, 0}; 
    static _Node C234 = { 4, 0}; 
 
    static _Node C311 = { 4, 0}; 
    static _Node C312 = { 4, 0}; 
    static _Node C313 = { 4, 0}; 
    static _Node C314 = { 4, 0}; 
    static _Node C315 = { 4, 0}; 
    static _Node C316 = { 4, 0}; 
    static _Node C317 = { 4, 0}; 
    static _Node C318 = { 4, 0}; 
    static _Node C319 = { 4, 0}; 
 
    static _Node C321 = { 4, 0}; 
    static _Node C322 = { 4, 0}; 
    static _Node C323 = { 4, 0}; 
    static _Node C324 = { 4, 0}; 
 
    static _Node C331 = { 4, 0}; 
    static _Node C332 = { 4, 0}; 
    static _Node C333 = { 4, 0}; 
    static _Node C334 = { 4, 0}; 
    static _Node C335 = { 4, 0,}; 
    static _Node C336 = { 4, 0}; 
    static _Node C337 = { 4, 0}; 
 
    static _Node C411 = { 4, 0}; 
    static _Node C412 = { 4, 0}; 
 
    static _Node C421 = { 4, 0}; 
    static _Node C422 = { 4, 0}; 
    static _Node C423 = { 4, 0}; 
    static _Node C424 = { 4, 0}; 
 
    static _Node C431 = { 4, 0}; 
    static _Node C432 = { 4, 0}; 
    static _Node C433 = { 4, 0}; 
 
    static _Node C521 = { 4, 0}; 
    static _Node C522 = { 4, 0}; 
    static _Node C523 = { 4, 0}; 
 
    static _Node C531 = { 4, 0}; 
    static _Node C532 = { 4, 0}; 
    static _Node C533 = { 4, 0}; 
    static _Node C534 = { 4, 0}; 
    static _Node C535 = { 4, 0}; 
    static _Node C536 = { 4, 0}; 
    static _Node C537 = { 4, 0}; 
 
    static _Node C551 = { 4, 0}; 
    static _Node C552 = { 4, 0}; 
    static _Node C553 = { 4, 0}; 
 
    static _Node C621 = { 4, 0}; 
    static _Node C622 = { 4, 0}; 
    static _Node C623 = { 4, 0}; 
    static _Node C624 = { 4, 0}; 
    static _Node C625 = { 4, 0}; 
    static _Node C626 = { 4, 0}; 
    static _Node C627 = { 4, 0}; 
    static _Node C628 = { 4, 0}; 
    static _Node C629 = { 4, 0}; 
 
 
                                       
/* 
 * Forward declarations 
 */                  
 
static void create_svn();   
static void svn_attach_proc(); 
static void svn_confirm_proc(); 
static void svn_get_entry_proc(); 
static void exit_proc(); 
static void LclInitializeList();  
Boolean SourceIsNodeParent(); 
static void SourceToggleNode(); 
static void SourceOpenNode(); 
static void SourceCloseNode(); 
NodePtr LclGetNodePtr(); 
static void LclCloseNode(); 
static void LclSetUpPixmap(); 
 
 
(4)int SourceNumComps = 2; 
int SourceNumEntries; 
                
static MrmHierarchy s_MrmHierarchy;   
static MrmType *dummy_class;       
(5)static char *db_filename_vec[] =      
  {"create_svn.uid"                   
  };      
 
 
 
/* The names and addresses of things that Mrm has to bind.  The names do 
 * not have to be in alphabetical order.  */ 
                 
static MrmRegisterArg reglist[] = { 
    {"svn_attach_proc", (caddr_t) svn_attach_proc}, 
    {"svn_confirm_proc", (caddr_t) svn_confirm_proc}, 
    {"exit_proc", (caddr_t) exit_proc}, 
    {"svn_get_entry_proc", (caddr_t) svn_get_entry_proc} 
}; 
 
 
static int reglist_num = (sizeof reglist / sizeof reglist [0]); 
 
 
int main(argc, argv) 
    unsigned int argc; 
    char **argv; 
{ 
         
    XtAppContext app_context; 
 
    MrmInitialize();   
    DXmInitialize();  
 
    toplevel = XtAppInitialize(&app_context, "svn example", NULL, 0, &argc, 
                             argv, NULL, NULL, 0);   
   
 
   /* Open the UID files (the output of the UIL compiler) in the hierarchy */ 
 
    if (MrmOpenHierarchy(1, 
      db_filename_vec,     
      NULL,                
      &s_MrmHierarchy)     
      !=MrmSUCCESS) 
          printf("can't open hierarchy");   
 
    MrmRegisterNames(reglist, reglist_num); 
 
               
    (6)if (MrmFetchWidget(s_MrmHierarchy, "main_svn", toplevel, 
      &svn_widget, &dummy_class) != MrmSUCCESS) 
        printf("can't fetch Svn widget"); 
 
     XtManageChild(svn_widget); 
                    
     XtRealizeWidget(toplevel); 
                         
     XtAppMainLoop(app_context);     
 
}                     
   .
   .
   .
 
 
/* 
 * The user pushed the exit button, so the application exits. 
 */ 
static void exit_proc(w, tag, reason) 
    Widget  w; 
    char  *tag; 
    XmAnyCallbackStruct *reason; 
{           
    if (tag != NULL) 
        printf("Exit - %s\n", tag); 
 
    exit(1); 
}           


Previous Next Contents Index