SgGraph(3X)SgGraph(3X)NAMESgGraph — 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 1.2.
DESCRIPTION
The SgGraph widget provides the application developer with the ability
to display any group of widgets as a graph, with each widget represent‐
ing 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 edit‐
ing 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, Com‐
posite, 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 remain‐
ing 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 connec‐
tions 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 con‐
junction 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 val‐
ues 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 inter‐
actively 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 sub‐
graph.
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 XmN‐
EVER. Otherwise, if nodes and/or arcs are added one at a time,
the layout algorithm may be called for each node and/or arc cre‐
ated. 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 sup‐
ported 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 interac‐
tively 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, other‐
wise if its value is XmVERTICAL the graph vertical (top to bot‐
tom) layout algorithm is invoked. Also, see under XmNarcDraw‐
Mode 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 direc‐
tion 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 verti‐
cally (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 chil‐
dren 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 cre‐
ated 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 pro‐
grammer 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, respec‐
tively. If multiple nodes are moved (because multiple nodes are
selected, and the one of the selected nodes are moved), the rea‐
son 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.
XmNselectSubgraphCallback, XmNselectArcCallback and XmNselectNodeCall‐
back
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 multi‐
ple 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, regard‐
less 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 cre‐
ated, 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, regard‐
less 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 interac‐
tively 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 dif‐
ferent 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 pro‐
duce 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 connect‐
ing 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 super‐
classes. 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 XmNnodeMoved‐
Callback.
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 XmN‐
graphChangedCallback, which is used primarily by the graph wid‐
get 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 XmNgraphChanged‐
Callback, which is used primarily by the graph widget overview
window.
XmCR_GRAPH_SCROLLED: The graph has been scrolled. This informa‐
tion 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 prob‐
ably 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 XmNar‐
cEditedCallback 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, XmN‐
newNodeCallback, 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 with‐
out 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 algo‐
rithm 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 sub‐
trees 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 unhigh‐
lights the indicated widget. However, moving back into the widget
without releasing the mouse button, re-highlights the indicated wid‐
get. 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 indi‐
cated 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 XmNSe‐
lecttArcCallback 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_wid‐
gets 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 XmNselectNode‐
Callback or XmNSelecttArcCallback are invoked.
EndAddArcOrNode: If a new node is being created, calls the XmNnewN‐
odeCallback list. If the value of the doit member of the calldata
parameter is not FALSE when the callback returns, a new node is cre‐
ated. 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 cre‐
ated.
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 SgCreate‐
ScrolledGraph() becomes "graphSW->ScrolledWindowClipWindow->graph".
Programmers who do not want these settings for the ScrolledWindow wid‐
get 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 success‐
ful, 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 asso‐
ciated 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 XmNselectArcCall‐
back 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 XmNselectArcCall‐
back 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 XmNdese‐
lectCallback 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, 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.
WidgetList SgGraphGetSelectedNodes (graph, n_nodes)
SgGraphWidget graph;
int *n_nodes;
SgGraphGetSelectedNodes will return a WidgetList containing all node
widgets in the selected_nodes list of graph.
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 XmNselectNode‐
Callback 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 XmNdese‐
lectCallback 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 must be treated as read-only.
void SgGraphRoots (graph, nodes, num_nodes)
SgGraphWidget graph;
WidgetList nodes;
int *num_nodes;
SgGraphGetRoots will insert into the WidgetList nodes all node widgets
in the user_roots list of graph.
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 behav‐
ior 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 ALSOCore(3X), Composite(3X), Constraint(3X), Manager(3X), SgArc(3x)SgGraph(3X)