SgGraph(3X)
SgGraph - An OSF/Motif-compatible graph widget.
As shipped in IRIX 6.5.22. Last changed in IRIX 6.5.22.
NAME SgGraph - An OSF/Motif-compatible graph widget. SYNOPSIS #include <Xm/Xm.h> #include <Sgm/Graph.h> VERSION This page documents the version of Sgm that accompanies Motif 2.1. DESCRIPTION The SgGraph widget provides the application developer with the ability to display any group of widgets as a graph, with each widget representing a node. The graph can be disconnected, as well as contain cycles. The arcs used to connect the nodes are instances of an SgArc widget, developed specifically for use with the SgGraph widget. Arcs may be undirected, directed, or bidirected. Note that the SgGraph widget does not understand the semantics of arc direction, ie. for layout and editing purposes, an arc will always have a parent and a child regardless of its direction. The SgGraph widget has the ability to arrange all nodes either horizontally or vertically according to an internal layout algorithm, and supports an edit mode in which arcs and nodes may be interactively repositioned as well as created. There is also a read-only mode in which all events are passed directly to the children of the Graph widget. In edit mode, the SgGraph takes over all device events for editing commands. CLASSES The SgGraph widget inherits behavior and resources from the Core, Composite, Constraint and XmManager classes. The class pointer is sgGraphWidgetClass The class name is SgGraph. NEW RESOURCES The Graph widget defines a set of resource types used by the programmer to specify the data for the graph. The programmer can also set the values for the Core, Composite, and Constraint widget classes to set attributes for this widget. The following table contains the set of resources defined by Graph. To reference a resource by name or by class in a .Xdefaults file, remove the XmN or XmC prefix and use the remaining letters. To specify one of the defined values for a resource in a .Xdefaults file, remove the Xm prefix and use the remaining letters (in either lower case or upper case, but include any underscores between words). The codes in the access column indicate if the given resource can be set at creation time (C), set by using XtSetValues (S), retrieved by using XtGetValues (G), or is not applicable (N/A). SgGraph Resource Set Name Class Type Default Access ______________________________________________________________________________________________________________ XmNeditable XmCEditable Boolean False CSG XmNallowMultipleSelections XmCAllowMultipleSelections Boolean True CSG XmNautoLayoutMode XmCAutoLayoutMode XmRAutoLayoutType XmNEVER CSG XmNlayoutProc XmCLayoutProc XmRPointer DoLayout CSG XmNarcDrawMode XmCArcDrawMode String XmPOSITION_RELATIVE CSG XmNdoubleClickInterval XmCDoubleClickInterval XmRInt 250 CSG XmNdefaultNodeClass XmCDefaultNodeClass XmRInt xmPushButtonGadgetClass CSG XmNinteractiveArcDirection XmCInteractiveArcDirection unsigned char XmUNDIRECTED CSG XmNmovableNodes XmCMovableNodes XmRBoolean TRUE CSG XmNtwinsVisible XmCTwinsVisible Boolean True CSG XmNreorient XmCReorient Boolean False CSG XmNreLayout XmCReLayout Boolean False CSG XmNorientation XmCOrientation XmROrientation XmHORIZONTAL CSG XmNchildSpacing XmCChildSpacing short 40 CSG XmNsiblingSpacing XmCSiblingSpacing short 30 CSG XmNnewArcCallback XmCCallback Pointer NULL C XmNnewNodeCallback XmCCallback Pointer NULL C XmNnodeMovedCallback XmCCallback Pointer NULL C XmNarcMovedCallback XmCCallback Pointer NULL C XmNdefaultActionCallback XmCCallback Pointer NULL C XmNselectNodeCallback XmCCallback Pointer NULL C XmNselectArcCallback XmCCallback Pointer NULL C XmNdeselectCallback XmCCallback Pointer NULL C XmNselectSubgraphCallback XmCCallback Pointer NULL C XmNgraphTooBigCallback XmCCallback Pointer NULL C XmNgraphChangedCallback XmCCallback Pointer NULL C XmNuserButtonCallback XmCCallback Pointer NULL C XmNptrCursor XmCCursor XmRCursor "left_ptr" CSG XmNmotionCursor XmCCursor XmRCursor "fleur" CSG XmNindicateCursor XmCCursor XmRCursor "crossshair" CSG XmNindicateChildCursor XmCCursor XmRCursor internal "C" CSG XmNindicateParentCursor XmCCursor XmRCursor internal "P" CSG XmNincrement XmCIncrement XmRInt 10 CSG XmNokToAdd XmCOkToAdd XmRBoolean TRUE CSG XmNeditableArcs XmCEditableArcs Boolean TRUE CSG XmNselectableArcs XmCSelectableArcs Boolean TRUE CSG XmNlayoutStyle XmCLayoutStyle XmRLayoutStyle XmGRAPH CSG XmNhighlightColor XmCHighlightColor XmRPixel white CSG XmNoverviewLineColor XmCoverviewLineColor XmRPixel black CSG XmNoverviewNodeColor XmCoverviewNodeColor XmRPixel black CSG XmNshowOverviewArcs XmShowOverviewArcs XmRBoolean TRUE CSG XmNskewOverviewScale XmSkewOverviewScale XmRBoolean FALSE CSG XmNshowCrossingArcs XmShowCrossingArcs XmRBoolean TRUE CSG XmNlayoutKey XmCLayoutKey XmRAtom NULL CSG XmNeditable When this resource is TRUE, the Graph widget is in edit mode. The user can interactively reposition individual and multiple nodes and arcs, add new nodes and arcs, and change the connections of arcs to nodes. (See Translations) XmNallowMultipleSelections When this resource is TRUE, (the default), multiple nodes and arcs can be selected, either by sweeping out a region on the screen with the mouse, or by holding down the SHIFT key in conjunction with mouse Button1, or by selecting a subtree using <Ctrl> Button1. If this resource is FALSE, all these operations are disabled. XmNautoLayoutMode This resource controls if and when the graph is relayed out as new arcs and nodes are added. This resource can take on the values XmNEVER, XmALWAYS, XmARCS_ONLY, XmNODES_ONLY, or XmPARTIAL, which behave in the following ways: XmNEVER: When XmNautoLayoutMode is XmNEVER, the graph widget never automatically lays out the graph. A new layout of the entire graph can be triggered by calling SgGraphLayout() or an relayout of a subpart of the graph can be triggered by calling XmRelaySubGraph(). A complete relayout can also be triggered by setting the XmNrelayout resource to TRUE. XmALWAYS: When XmNautoLayoutMode is XmALWAYS, the graph widget triggers a relayout whenever a new node or arc is managed, or when a arc is moved from one node to another. This happens regardless of whether or not the change is made interactively or programatically. XmARCS_ONLY: When XmNautoLayoutMode is XmARCS_ONLY, the graph widget triggers a complete relayout whenever an arc is added or moved. XmNODES_ONLY: When XmNautoLayoutMode is XmNEVER, the graph widget triggers a complete relayout whenever a node is interactively added. XmPARTIAL: When XmNautoLayoutMode is XmNEVER, the graph widget triggers a partial relayout whenever an arc is added or moved. The relayout is performed by calling XmRelaySubgraph, using the value of the arc's XmNfrom resource as the root of a subgraph. It is not expected that any of these approaches will perform optimally according to the users expectations, but may be useful in some cases. Be careful about setting these before building a graph. For fastest startup time, set XmNautoLayoutMode to XmNEVER. Otherwise, if nodes and/or arcs are added one at a time, the layout algorithm may be called for each node and/or arc created. The default value is XmNEVER. XmNarcDrawMode The value of this resource determines how all arcs in the graph are drawn. If XmNarcDrawMode is XmPOSITION_RELATIVE (the default), arcs are drawn from the center of the parent node to the center of the child node (without actually overlapping the node widgets). If XmNarcDrawMode is XmPOSITION_FIXED, the arcs will be drawn from the middle bottom of the parent to the middle top of the child if XmNorientation is XmVERTICAL, and from the middle right of the parent to the middle left of the child if XmNorientation is XmHORIZONTAL. If arcDrawMode is set to XmPOSITION_PROPORTIONAL, then the graph draws connecting arcs according to the value of the XmNfromSide, XmNtoSide, XmNfromPosition, and amNtoPosition resources supported by each arc widget. This mode allows applications to have fine control over the location of the arcs at each connecting point. See SgArc(3) for details. XmNdoubleClickInterval The timer interval between mouse clicks recognized as a double click by the graph widget. XmNdefaultNodeClass When XmNeditable is TRUE, the user can add new nodes interactively to the graph. The value of this resource determines what type of widget is created and must be a class pointer to a valid widget class. The default is an XmPushButtonGadget. XmNinteractiveArcDirection When an arc is drawn interactively, this resource determines whether the arc is undirected, bidirected, or directed. XmNmovableNodes If TRUE, nodes can be moved interactively when the graph is in edit mode. When false, nodes cannot be repositioned. XmNtwinsVisible When this resource is FALSE (the default), arcs that extend between the same 2 nodes will be drawn on top of the other, in arbitrary order. When this resource is TRUE, 1 arc is drawn as a straight line and the rest are drawn as non-overlapping curves between the same 2 points. XmNorientation If this resource is XmHORIZONTAL the graph horizontal (left to right) layout algorithm is invoked on the graph widget, otherwise if its value is XmVERTICAL the graph vertical (top to bottom) layout algorithm is invoked. Also, see under XmNarcDrawMode for the effect of this resource on how arcs are drawn. XmNreorient Any time this resource is set to TRUE, regardless of its current value, the graph widget is re-laid out vertically if its direction is currently XmHORIZONTAL, or horizontally otherwise. XmNreLayout Any time this resource is set to TRUE, regardless of its current value, the graph widget is re-laid out in the current direction. XmNorientation This resource determines whether the graph is laid out vertically (XmVERTICAL) or horizontally (XmHORIZONTAL). The default is XMHORIZONTAL. XmNchildSpacing and XmNsiblingSpacing These 2 resources determine the space the layout algorithm will leave between parent and child (childSpacing) and between children of the same node (siblingSpacing). The value of these resources is interpreted in terms of the current value of the XmNunitType resource. XmNnewArcCallback and XmNnewNodeCallback This callback list is invoked when a new arc or node is created interactively by the user. The arc or node is automatically created by the system and positioned according to the users instructions. In the case of a node, the default node is a XmPushButtonGadget. The application's XmNnewNodeCallback or XmNnewArcCallback is called before the arc or node is managed, with the node or arc as the widget member of the call data struct, allowing the application to create or set whatever information the arc or node represents and to modify the widgets resources. The reason member of the call data structure is XmCR_NEW_ARC or XmCR_NEW_NODE, respectively. XmNarcMovedCallback and XmNnodeMovedCallback These callback lists are invoked when an arc or node is moved interactively by the user. When a node is being moved, the node is first positioned according to the user's instructions and then the application's callback is called. When an arc is moved, the callback is invoked before the arc is moved to give the programmer the opportunity to disallow the move (See Callbacks). The argument list to the callbacks includes the the arc widget, and the node widget respectively. The reason member of the callback struct is XmCR_ARC_MOVED or XmCR_NODE_MOVED, respectively. If multiple nodes are moved (because multiple nodes are selected, and the one of the selected nodes are moved), the reason will be XmCR_NODES_MOVED, and the widget member of the call data struct will indicate the first widget in the list of selected nodes, and the complete list of moved nodes will be given in the selected_nodes. XmNdefaultActionCallback This callback is invoked when the user double clicks on a node or arc when the graph is in edit mode. XmNselectNodeCallback XmNselectSubgraphCallback, XmNselectArcCallback and These callback lists are invoked when an arc, subgraph, or node is selected. The argument list to the callbacks includes the widget of the subgraph root, the arc widget, and the node widget respectively. The reasons are XmCR_SELECT_SUBGRAPH, XmCR_SELECT_ARC, and XmCR_SELECT_NODE, respectively. If multiple arcs and/or nodes are selected simultaneously (by sweeping out a region with the mouse), the reason is given as XmCR_SELECT_ARCS, XmCR_SELECT_NODES, or XmCR_SELECT_ARCS_AND_NODES. In this case, the widget member of the call data struct will indicate the first widget in the list of selected nodes or arcs, and the complete list of selected arcs and/or nodes will be given in the selected_arcs and selected_nodes lists. XmNdeselectCallback This callback is called when any arc or node is deselected. XmNgraphTooBigCallback This callback is called when the graph window would have to exceed the maximum size of an X window to display the graph. XmNgraphChangedCallback This callback is called when any child of the graph widget moves or the graph structure is changed in anyway. XmNuserButtonCallback This callback is called when mouse button 3 is pressed, as a hook for pop up menus. XmNptrCursor The "normal" cursor. If a new cursor is installed, the Graph widget frees the previous cursor, regardless of who created the cursor. XmNmotionCursor The cursor shown when a node is being moved. If a new cursor is installed, the Graph widget frees the previous cursor, regardless of who created the cursor. XmNindicateCursor The cursor shown when selecting an arc or node, while the mouse button is depressed. If a new cursor is installed, the Graph widget frees the previous cursor, regardless of who created the cursor. XmNindicateChildCursor The cursor shown when an arc is being moved if the end being edited is the "to" or child end. If the arc is being created, this cursor will be displayed only after the sprite is moved out of the parent node. If a new cursor is installed, the Graph widget frees the previous cursor, regardless of who created the cursor. XmNindicateParentCursor The cursor shown when an arc is being moved if the end being edited is the "from" or parent end. When a new arc is being created, the initial node under the sprite is assumed to be the parent, and the XmNindicateParentCursor is displayed until the sprite is moved out of the parent node. If a new cursor is installed, the Graph widget frees the previous cursor, regardless of who created the cursor. XmNincrement Controls the number of pixels the graph scrolls when scrolled in individual increments. See XmScrollBar(3). XmNokToAdd If this resource is TRUE, widgets and arcs can be added interactively to a graph. XmNeditableArcs If this resource is TRUE, arcs can be added interactively to a graph and existing arcs can be edited to point to and from different nodes. XmNselectableArcs If this resource is TRUE, arcs can be selected and respond to double-clicks. XmNlayoutStyle This resource works with the internal layout algorithm to produce a "normal" graph layout or a "butterfly" layout. Possible values are XmGRAPH (the default) or XmBUTTERFLY. XmNhighlightColor The color used to highlight arcs when they are selected. XmNoverviewLineColor The color used to draw arcs in the overview. XmNoverviewNodeColor The color used to draw unselected nodes in the overview. XmNshowOverviewArcs If TRUE, arcs are drawn in the overview window. If FALSE, only nodes are drawn. XmNskewOverviewScale If TRUE, the overview will be scaled to fill the overview in both directions. If FALSE, the overview will maintain the true proportion of the graph. XmNshowCrossingArcs If TRUE, display all arcs in the graph even if neither connecting node is visible. If FALSE, the graph prunes away arcs that simply cross the screen. The result is a cleaner looking and faster scrolling display, but at the cost of some accuracy and some disconcerting flutter as arcs come and go in some graphs. XmNallowGrandChildInput When in edit mode, the graph widget steals input from all nodes. If a node is a complex graph hierarchy, it may at times be desirable to have the graph grab events from all children of the complex node, and at other times to only grab events from the top-most widget in a node, allowing children to receive input. If this resource is TRUE, children of direct children of the graph will handle their own events. Otherwise, the graph grabs all input. The default value is TRUE. Inherited Resources SgGraph inherits behavior and resources from the following superclasses. For a complete description of these resources, refer to the man page for that superclass. XmManager Resource Set Name Class Type Default Access ____________________________________________________________________ XmNforeground XmCForeground Pixel dynamic CSG XmNhelpCallback XmCCallback XtCallbackList NULL C XmNunitType XmCUnitType unsigned char XmPIXELS CSG XmNuserData XmCUserData caddr_t NULL CSG Core Resource Set Name Class Type Default Access ____________________________________________________________________________________________ XmNaccelerators XmCAccelerators XtTranslations NULL CSG XmNancestorSensitive XmCSensitive Boolean True G XmNbackground XmCBackground Pixel dynamic CSG XmNbackgroundPixmap XmCPixmap Pixmap XmUNSPECIFIED_PIXMAP CSG XmNborderColor XmCBorderColor Pixel Black CSG XmNborderPixmap XmCPixmap Pixmap XmUNSPECIFIED_PIXMAP CSG XmNborderWidth XmCBorderWidth Dimension 0 CSG XmNcolormap XmCColormap Colormap XtCopyFromParent CG XmNdepth XmCDepth int XtCopyFromParent CG XmNdestroyCallback XmCCallback XtCallbackList NULL C XmNheight XmCHeight Dimension 0 CSG XmNmappedWhenManaged XmCMappedWhenManaged Boolean True CSG XmNscreen XmCScreen Pointer XtCopyScreen CG XmNsensitive XmCSensitive Boolean True CSG XmNtranslations XmCTranslations XtTranslations NULL CSG XmNarcWidth XmCArcWidth Int 0 CSG XmNx XmCPosition Position 0 CSG XmNy XmCPosition Position 0 CSG Callback Information The following structure is returned with each callback. typedef struct { int reason; XEvent *event; Boolean interactive; WidgetList selected_widgets; int num_selected_widgets; WidgetList selected_arcs; int num_selected_arcs Widget widget; Widget old_to, old_from, new_to, new_from; Boolean doit; } SgGraphCallbackStruct; reason Indicates why the callback was invoked. Possible reasons are: XmCR_NEW_ARC: A new arc has been created. XmCR_NEW_NODE: A new arc has been created. XmCR_NODE_MOVED: One node has been moved. XmCR_NODES_MOVED: Multiple nodes have been moved. XmCR_ARC_MOVED: An arc has been moved. This implies the arc has changed the nodes it points to, not a physical change in the location of the arcs. This would be indicated by a XmNnodeMovedCallback. XmCR_SELECT_NODE: A node has been selected. XmCR_SELECT_NODES: Multiple nodes have been selected. XmCR_SELECT_ARC: An arc has been selected. XmCR_SELECT_ARCS: Multiple nodes have been selected. XmCR_SELECT_ARCS_AND_NODES: Multiple nodes and arcs have been selected. XmCR_SELECT_SUBGRAPH: A subgraph has been selected. XmCR_NODE_DOUBLE_CLICK: A double click on a node. XmCR_ARC_DOUBLE_CLICK: A double click on an Arc widget. XmCR_DOUBLE_CLICK: A double click not over a node or arc has occurred. XmCR_DESELECT_ARC: One or more arcs has been deselected. XmCR_DESELECT_NODE: One or more nodes has been deselected. XmCR_OVERVIEW_MARK_CHANGED: The mark resource color on a node has changed. This information is reported by the XmNgraphChangedCallback, which is used primarily by the graph widget overview window. XmCR_SIZE_CHANGED: The size of the graph (i.e. the width or height of a rectangle enclosing all nodes and arcs) has changed. This information is reported by the XmNgraphChangedCallback, which is used primarily by the graph widget overview window. XmCR_LAYOUT_CHANGED: The layout of the nodes in the graph has changed. This information is reported by the XmNgraphChangedCallback, which is used primarily by the graph widget overview window. XmCR_GRAPH_SCROLLED: The graph has been scrolled. This information is reported by the XmNgraphChangedCallback, which is used primarily by the graph widget overview window. XmCR_BUTTON_OVER_GADGET: The user has pressed the mouse "user" button over a gadget used as a graph node while in edit mode. This value is used by the XmNuserButtonCallback callback, which is meant to support popup menus. XmCR_BUTTON_OVER_WIDGET: The user has pressed the mouse "user" button over a widget used as a graph node while in edit mode. This value is used by the XmNuserButtonCallback callback, which is meant to support popup. XmCR_BUTTON_OVER_GRAPH: The user has pressed the mouse "user button" over the gadget window. This value is used by the XmNuserButtonCallback callback, which is meant to support popup event Points to the XEvent that triggered the callback. widget Indicates the current arc or node widget associated with this callback. interactive TRUE if the callback was invoked as a result of a user action. In the current Graph, this is always TRUE. This field will probably dissapear soon. At this point, all relevant callbacks are interactive. selected_widgets Always indicates the list of currently selected nodes in an array containing num_selected_widgets. This list belongs the the Graph and MUST be treated as READ-ONLY. num_selected_widgets The number of selected node widgets. selected_arcs Always indicates the list of currently selected arcs, in an array containing num_selected_arcs. This list belongs the the Graph and MUST be treated as READ- ONLY. num_selected_arcs The number of selected arc widgets. old_to, old_from, new_to, new_from If an arc has been moved, the nodes the arc formerly connected, and the nodes the arc will now connect. Only valid for XmNarcEditedCallback and XmNarcMovedCallback. doit This member is initialized to TRUE. If the application wishes to terminate or disallow certain operations, this field can be set to FALSE before the callback returns. An example of how this might be used is if the application wishes to create a different type of node widget than the default. If this member is set to FALSE in an XmNnewNodeCallback, the Graph widget will destroy the node widget it has created. The application can them create a new node at the position of the interactively created widget. Only used with XmNarcEditedCallback, XmNarcMovedCallback, XmNnewNodeCallback, and XmNnewArcCallback lists. Layout Algorithm The current Graph layout algorithm is a simple and efficient tree layout algorithm adapted to handle forests of nodes. It works as follows: It first compiles a list of "roots" by looking for, in order,: (1) a unique node of each subgraph selected by the user via the SgGraphInsertRoots function, (2) any node without a parent, (3) of those strongly connected components of the graph (a strongly connected component is a subgraph in which any node can reach all other nodes) which cannot be reached by a root chosen previously, a node is chosen at random. The algorithm then traverses the subgraphs rooted at each node in the "roots" list, converting each in turn into a tree. If a node belongs to more than one of these subgraphs, it will be placed in the tree where its deepest parent belongs. The algorithm then performs the actual layout, and finally reconverts the subtrees back to the original graph. The nodes in the "roots" list will be laid out, at the same level, as the topmost (vertical layout) or rightmost (horizontal layout) widgets in their respective subgraph, while the rest of the nodes will be placed under (to the right of) them. If any of the subgraphs have cycles the layout algorithm will arbitrarily "break" them for layout purposes only. Behavior SgGraph behavior is summarized below. None <Btn1Down>: Indicate() Arm() Ctrl <Btn1Down>: AddIndicate() Shift <Btn1Down>: IndicateSubtree() None <Btn2Down>: SelectForMotion() Shift<Btn2Down>: StartAddNode() None <Btn1Up>: EndButtonAction() Activate() Ctrl <Btn1Up>: EndButtonAction() Shift <Btn1Up>: EndButtonAction() None <Btn2Up>: EndButtonAction() Shift <Btn2Up>: EndButtonAction() Ctrl <Btn2Up>: EndButtonAction() <Btn1Motion>: HandleMotion() EnterLeaveMotion() <Btn2Motion>: HandleMotion() <EnterWindow>: Enter() <FocusIn>: FocusIn() <FocusOut>: FocusOut() <Key>F1: Help() ACTIONS Indicate: If in edit mode, and the mouse is on a node widget or over an arc, it highlights that node or arc and begins a selection process. If the mouse is not over a node it also begins a rubberbanding selection process. See HandleMotion() and EndButtonAction(). AddIndicate: If in edit mode, and the mouse is on a node widget or over an arc, it highlights that node or arc and begins a selection process without deselecting already selected arcs or nodes. See HandleMotion() and EndButtonAction(). IndicateSubtree: If in edit mode, and the mouse is on a node widget, it highlights the subtree whose root is that node and begins a selection process. See HandleMotion() and EndButtonAction(). StartAddArcOrNode: If in edit mode, and the sprite is not over any existing node, displays a rubberband box to prompt the user to position a new node widget. If over a node, prompts the user with a rubberband line to position the other end of a new arc. HandleMotion(): Handles all mouse motion depending on a state variable set by the button down action. Conceptually, this action can be one of: Cancel(): If in edit mode, moving out of the indicated widget unhighlights the indicated widget. However, moving back into the widget without releasing the mouse button, re-highlights the indicated widget. Thus a selection can be terminated by moving out of the widget before releasing the mouse button. CancelSubtree(): If in edit mode, moving out of the indicated widget unhighlights the indicated subtree. However, moving back into the widget without releasing the mouse button, re-highlights the indicated subtree. Thus a selection can be terminated by moving out of the widget before releasing the mouse button. Motion: Moves a node or arc to a new position. EndButtonAction(): Handles all mouse button up events depending on a state variable set by the button down action. Conceptually, this action can be one of: Select: If in edit mode and the mouse is on a node or arc widget The node is persistently highlighted and added to the list of selected widgets, after unhighlighting any previously selected widgets and removing them from the list. The XmNselectNodeCallback or XmNSelecttArcCallback are invoked. AddSelect: If in edit mode and the mouse is on a node or arc widget, the node is persistently highlighted and added to the list of selected widgets. Previously selected widgets remain selected. The XmNselectNodeCallback or XmNSelecttArcCallback are invoked, with the newly selected widget indicated by the widget member of the calldata, and the entire set of selected widgets indicated by the selected_widgets and selected_arcs members. SelectTree: If in edit mode and the mouse is on a node, the subtree whose root is that node is persistently highlighted and added to the list of selected widgets, after unhighlighting any previously selected widgets and removing them from the list. The XmNselectNodeCallback or XmNSelecttArcCallback are invoked. EndAddArcOrNode: If a new node is being created, calls the XmNnewNodeCallback list. If the value of the doit member of the calldata parameter is not FALSE when the callback returns, a new node is created. If a new arc is being created, the XmNnewArcCallback callback list is invoked. If the value of the doit member of the calldata parameter is not FALSE when the callback returns, a new arc is created. EndMotion: Ends the movement of an arc or node. Nodes are simply moved physically, and the XmNnodeMovedCallback is invoked. If the sprite is not over a valid node when this procedure is called, the move is terminated. If an arc is moved, the XmNarcEditedCallback is invoked on the arc, and the XmNarcMovedCallback is invoked on the graph widget, with the arc as the widget member. The old_to and old_from members of the calldata indicate the original nodes to which the arc was connected, while the new_to and new_from indicate the nodes to which the user has indicated the arc should be connected. If the doit member of the calldata is not set to FALSE when either callback returns, the arc is actually moved. EDIT MODE The translations discussed above are only valid while in edit mode, that is when XmNeditable is TRUE. While not in edit mode, the graph widget acts as a layout manager only, and passes all events on to its children without interference. UTILITY FUNCTIONS Widget SgCreateGraph (parent, name, arglist, argcount) Widget parent; char *name; ArgList arglist; Cardinal argcount; SgCreateGraph creates an unmanaged instance of a Graph widget and returns the associated widget ID. Widget SgCreateManagedGraph (parent, name, arglist, argcount) Widget parent; char *name; ArgList arglist; Cardinal argcount; SgCreateManagedGraph creates a managed instance of a Graph widget and returns the associated widget ID. Widget SgCreateScrolledGraph (parent, name, arglist, argcount) Widget parent; char *name; ArgList arglist; Cardinal argcount; SgCreateScrolledGraph creates an instance of a Graph widget as a child of an XmScrolledWindow widget and returns the widget ID of the Graph widget. Notice that this function uses the AUTOMATIC scrollbar mode of the XmScrolledWindow widget. This creates a ScrolledWindowClipWindow widget, which becomes the parent of the SgGraph widget. So the widget hierarchy of an SgGraph widget named "graph" created with SgCreateScrolledGraph() becomes "graphSW- >ScrolledWindowClipWindow->graph". Programmers who do not want these settings for the ScrolledWindow widget can create their own instead of using the convenience function. However, the Graph widget does extensive optimizations based on the existence of the ScrolledWindow's clipWindow. Changing the way in which the ScrolledWindow is configured will eliminate these optimizations. WidgetList SgGraphGetArcsBetweenNodes (graph, from, to, numArcs) SgGraphWidget graph; Widget from; Widget to; int* numArcs; SgGraphGetArcsBetweenNodes returns a list of all SgArc widgets that extend from from to to. If no such arc exists, returns NULL. This list must be treated as read-only. Boolean SgGraphRemoveArcBetweenNodes (graph, widget1, widget2) SgGraphWidget graph; Widget widget1; Widget widget2; SgGraphRemoveArcBetweenNodes destroys all arcs between widget1, and widget2 which must be node widgets in graph. Returns True if successful, False otherwise. Boolean SgGraphMoveArc (graph, arc, from, to) SgGraphWidget graph; ArcWidget arc; Widget from, to; XmMoveArc changes the end nodes of arc from the current nodes to the given from and to nodes. Returns True if successful, False otherwise. void SgGraphNumNodeArcs (graph, node, n_from, n_to) SgGraphWidget graph; Widget node; int *n_from, *n_to; SgGraphNumNodeArcs assigns to n_from and n_to the number of arcs associated with node. node must be a node widget in graph. void SgGraphGetNodeArcs (graph, node, from, to, n_from, n_to) SgGraphWidget graph; Widget node; WidgetList *from, *to; int *n_from, *n_to; SgGraphGetNodeArcs will put in the from and to WidgetLists the arcs associated with the given node widget. from and to must be treated as read-only. n_from and n_to return the number of arcs. node must be a node widget in graph. void SgGraphGetArcNodes (graph, arc, from, to) SgGraphWidget graph; ArcWidget arc; Widget *from, *to; SgGraphGetArcNodes will store in the from and to widgets the nodes associated with arc. void SgGraphSelectArcs (graph, arcs, n_arcs, notify) SgGraphWidget graph; WidgetList arcs; int n_arcs; Boolean notify; SgGraphSelectArcs adds to the selected_arcs list of graph the first n_arcs in the WidgetList arcs. If notify is true, the XmNselectArcCallback list is invoked. void SgGraphSelectArc (graph, arc, notify) SgGraphWidget graph; Widget arc; Boolean notify; SgGraphSelectArc adds to the selected_arcs list of graph the given arc. arc must be a child of graph. If notify is true, the XmNselectArcCallback list is invoked. void SgGraphUnselectArcs (graph, arcs, n_arcs, notify) SgGraphWidget graph; WidgetList arcs; int n_arcs; Boolean notify; SgGraphUnselectArcs removes from the selected_arcs list of graph the first n_arcs in the WidgetList arcs. If notify is true, the XmNdeselectCallback list is invoked. void SgGraphUnselectArc (graph, arc, notify) SgGraphWidget graph; Widget arc; Boolean notify; SgGraphUnselectArc removes arc from the selected_arcs list of graph. If notify is true, the XmNdeselectCallback list is invoked. int SgGraphNumSelectedArcs (graph) SgGraphWidget graph; SgGraphNumSelectedArcs returns the number of arcs in the selected_arcs list of graph. WidgetList SgGraphGetSelectedArcs (graph, arcs, n_arcs) SgGraphWidget graph; int *n_arcs; SgGraphGetSelectedArcs will return a WidgetList arcs containing all currently selected arcs. This list must be treated as read-only. Boolean SgGraphIsSelectedArc (graph, arc) SgGraphWidget graph; Widget arc; SgGraphIsSelectedArc returns TRUE of the given arc is currently selected. int SgGraphNumArcs (graph) SgGraphWidget graph; SgGraphNumArcs returns the number of arc widgets in graph. WidgetList XmGetGraphArcs (graph, arcs, num_arcs) SgGraphWidget graph; int *num_arcs; SgGraphGetArcs will return a WidgetList containing all arc widgets in graph. This list must be treated as read-only. WidgetList XmGetGraphNodes (graph, arcs, num_nodes) SgGraphWidget graph; int *num_nodes; XmGetGraphNodes will return a WidgetList containing all node widgets in graph. This list must be treated as read-only. int SgGraphNumSelectedNodes (graph) SgGraphWidget graph; SgGraphNumSelectedNodes returns the number of node widgets in the selected_nodes list of graph. Boolean SgGraphMoveNode (graph, node, x, y) SgGraphWidget graph; Widget node; Position x, y; SgGraphMoveNode changes the position of node to x, and y. node must be a node widget in graph. Returns True if successful, False otherwise. void SgGraphGetSelectedNodes (graph, nodes, n_nodes) SgGraphWidget graph; WidgetList nodes; int *n_nodes; SgGraphGetSelectedNodes will return a WidgetList containing all node widgets in the selected_nodes list of graph. This list is owned by the widget instance and must be treated as read-only. This list will be overwritten when SgGraphGetSelectedNodes or SgGraphGetRoots are called. Widget SgGraphInputOverArc (graph, x, y) SgGraphWidget graph; Position x, y; SgGraphInputOverArc returns an SgArc widget that contains the point (x, y). If no such arc exists, SgGraphInputOverArc returns NULL. void SgGraphSelectNodes (graph, nodes, n_nodes, notify) SgGraphWidget graph; WidgetList nodes; int n_nodes; Boolean notify;; SgGraphSelectNodes adds to the selected_nodes list of graph the first n_nodes in the WidgetList nodes. If notify is true, the XmNselectNodeCallback list is invoked. void SgGraphSelectNode (graph, node, notify) SgGraphWidget graph; Widget node; Boolean notify; SgGraphSelectNode adds node to the selected_nodes list of graph. node must be a child of graph. If notify is true, the XmNselectNodeCallback list is invoked. void SgGraphDestroySelectedArcsOrNodes (graph) SgGraphWidget graph; SgGraphDestroySelectedArcsOrNodes calls XtDestroyWidget on all selected arcs or nodes. void SgGraphDestroyAllArcs (graph) SgGraphWidget graph; SgGraphDestroyAllArcs calls XtDestroyWidget on all arcs. void SgGraphDestroyAllNodes (graph) SgGraphWidget graph; SgGraphDestroyAllNodes calls XtDestroyWidget on all node widgets. void SgGraphIsSelectedNode (graph, node) SgGraphWidget graph; Widget node; SgGraphIsSelectedNode returns TRUE of the given node is currently selected. void XmUnselectNodes (graph, nodes, n_nodes, notify) SgGraphWidget graph; WidgetList nodes; int n_nodes; Boolean notify; SgGraphUnselectNodes removes from the selected_nodes list of graph the first n_nodes in the WidgetList nodes. If notify is true, the XmNdeselectCallback list is invoked. void SgGraphUnselectNode (graph, node, notify) SgGraphWidget graph; Widget node; Boolean notify; SgGraphUnselectNode removes node from the selected_nodes list of graph. If notify is true, the XmNdeselectCallback list is invoked. void SgGraphNumNodes (graph) SgGraphWidget graph; SgGraphNumNodes returns the number of node widgets in graph, not including the dummy node created by the graph. void SgGraphGetNodes (graph, nodes) SgGraphWidget graph; WidgetList nodes; SgGraphGetNodes will return a WidgetList containing all node widgets in graph. This list is owned by the widget instance and must be treated as read-only. WidgetList SgGraphGetRoots (graph, num_nodes) SgGraphWidget graph; int *num_nodes; SgGraphGetRoots will return a WidgetList containing all widgets in the user_roots list of graph. This list is owned by the widget instance and must be treated as read-only. This list will be overwritten when SgGraphGetSelectedNodes or SgGraphGetRoots are called. void SgGraphInsertRoots (graph, nodes, n_nodes) SgGraphWidget graph; WidgetList nodes; int n_nodes; SgGraphInsertRoots adds to the user_roots list of graph the first n_nodes in the WidgetList nodes. void SgGraphRemoveRoots (graph, nodes, n_nodes) SgGraphWidget graph; WidgetList nodes; int n_nodes; SgGraphRemoveRoots removes from the user_roots list of graph the first n_nodes in the WidgetList nodes. void SgGraphNumRoots (graph) SgGraphWidget graph; SgGraphNumRoots returns the number of node widgets in the user_roots list of graph. void SgGraphLayout (graph) SgGraphWidget graph; SgGraphLayout forces a relayout of the entire graph. extern SgGraphRelaySubgraph (graph, node) SgGraphWidget graph; Widget node; SgGraphRelaySubgraph relays the subgraph rooted at the node widget node. extern SgGraphCenterAroundWidget (graph, node) SgGraphWidget graph; Widget node; SgGraphCenterAroundWidget attempts to scroll a scrolled graph to make node appear in the center of the screen. extern SgGraphMakeWidgetVisible (graph, node) SgGraphWidget graph; Widget node; SgGraphMakeWidgetVisible attempts to scroll a scrolled graph to make node appear in the center of the screen, unless the widget is already visible. extern Widget SgGraphCreateOverView (Widget graph, Widget parent); Creates a small, view-only version of the contents of the given graph, as a child of the provided parent. Typically, this is a popup shell, providing an optional overview of a large graph. The overview is drawn in an XmDrawingArea widget, which is returned by this function. The drawing area widget is not managed. extern void SgGraphSetButterflyRoot(Widget graph, Widget node); When the value of XmNlayoutStyle is XmBUTTERFLY, the graph widget arranges a set of children according to the parents and children of one node. This function allows that node to be specified. The given node will be centered in the graph, with the parents of that node to the left, and its children to the right. extern void SgGraphZoom(Widget graph, float factor); This function allows programs to simulate a crude form of zooming by applying a scale factor to the spacing between arcs and nodes. It is a shortcut for setting the XmNchildSpacing and XmNsiblingSpacing resources. This function also forces a relayout. extern void SgGraphDontAdjustSize(Widget graph); If called, this function function prevents the graph widget from attempting any further size adjustments, such as may occur when the graph is layed out, or nodes are added. This function can be used to prevent excessive flashing when performing a group of operations. This function should be called in matching pairs with SgGraphAdjustSize() extern void SgGraphAdjustSize(Widget graph); This function function recomputes the size of the graph, updating scrollbars, the optional overview window, and so on. It is meant to be called after SgGraphDontAdjustSize() to restore the normal graph behavior as nodes are added, the graph is layed out, and so on. extern void SgGraphUnmanageAll(Widget graph); This convenience function unmanages all widgets currently managed by the graph. extern void SgGraphManageAll(Widget graph); This convenience function manages all widgets currently managed by a graph widget. extern void SgGraphShowCoverWindow(Widget graph); This function displays an X window that completely covers the graph widget. When performing extensive updates on the graph, it can be less visually distracting to the user for the graph to simply go blank, and then be shown in its new state, than to see the changes as they occur. Bracketing sections of code that perform updates with calls to SgGraphShowCoverWindow and SgGraphHideCoverWindow can give the user a smoother perception of the process. extern void SgGraphHideCoverWindow(Widget); Removes the cover window displayed by ShGraphShowCoverWindow(). extern Boolean SgGraphPrint(Widget graph, char *fileName); This function saves the current graph as a postscript print file. The postscript processing leaves much to be desired. extern void SgGraphSelectSubtree(Widget graph, Widget target); Select all nodes below the given target. BUGS Performance begins to break down at around 2000 nodes if gadgets are used as nodes, far less if widgets are used as nodes. The performance falls off much more rapidly with a large number of arcs, particularly if the graph is not "well-behaved". SEE ALSO Core(3X), Composite(3X), Constraint(3X), Manager(3X), SgArc(3x)