Blame lib/Xm/Tree.c

Packit b099d7
/*
Packit b099d7
 * Motif
Packit b099d7
 *
Packit b099d7
 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are free software; you can
Packit b099d7
 * redistribute them and/or modify them under the terms of the GNU
Packit b099d7
 * Lesser General Public License as published by the Free Software
Packit b099d7
 * Foundation; either version 2 of the License, or (at your option)
Packit b099d7
 * any later version.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are distributed in the hope that
Packit b099d7
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
Packit b099d7
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Packit b099d7
 * PURPOSE. See the GNU Lesser General Public License for more
Packit b099d7
 * details.
Packit b099d7
 *
Packit b099d7
 * You should have received a copy of the GNU Lesser General Public
Packit b099d7
 * License along with these librararies and programs; if not, write
Packit b099d7
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Packit b099d7
 * Floor, Boston, MA 02110-1301 USA
Packit b099d7
 * 
Packit b099d7
 */
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	INCLUDE FILES
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
#include <stdio.h>
Packit b099d7
#include "XmI.h"
Packit b099d7
#include "xmlist.h"
Packit b099d7
#include <Xm/TreeP.h>
Packit b099d7
#include <X11/Xutil.h>
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	TYPEDEFS AND DEFINES
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
#define SUPERCLASS (&xmHierarchyClassRec)
Packit b099d7
Packit b099d7
#define INDENT_SPACE 30
Packit b099d7
Packit b099d7
typedef struct {
Packit b099d7
  int x;
Packit b099d7
  int y;
Packit b099d7
} LadderPoint;
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	MACROS
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	GLOBAL DECLARATIONS
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	STATIC FUNCTION DECLARATIONS
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
static void Resize(Widget), ClassInit(void);
Packit b099d7
static void Realize(Widget, Mask *, XSetWindowAttributes *);
Packit b099d7
static void Redisplay(Widget, XEvent *, Region);
Packit b099d7
static void ClassPartInitialize(WidgetClass w_class);
Packit b099d7
static void Initialize(Widget, Widget, ArgList, Cardinal *);
Packit b099d7
static void ConstraintInitialize(Widget, Widget, ArgList, Cardinal *);
Packit b099d7
static void ConstraintDestroy(Widget);
Packit b099d7
static void TreeDestroy(Widget);
Packit b099d7
static void ToggleNodeState(Widget, XtPointer, XtPointer);
Packit b099d7
Packit b099d7
static XtGeometryResult QueryGeometry(Widget, 
Packit b099d7
				      XtWidgetGeometry *, XtWidgetGeometry *);
Packit b099d7
Packit b099d7
static Boolean ConstraintSetValues(Widget, Widget, Widget, ArgList, Cardinal*);
Packit b099d7
static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal*);
Packit b099d7
Packit b099d7
static XtGeometryResult GeometryManager(Widget, 
Packit b099d7
				      XtWidgetGeometry *, XtWidgetGeometry *);
Packit b099d7
Packit b099d7
/************************
Packit b099d7
 * Actions and callbacks.
Packit b099d7
 ************************/
Packit b099d7
Packit b099d7
/*********************
Packit b099d7
 * Internal Routines.
Packit b099d7
 *********************/
Packit b099d7
Packit b099d7
static Boolean CvtStringToConnectStyle(Display *, XrmValuePtr, Cardinal *, 
Packit b099d7
				       XrmValuePtr, XrmValuePtr);
Packit b099d7
static Boolean CvtStringToCompressStyle(Display *, XrmValuePtr, Cardinal *, 
Packit b099d7
				       XrmValuePtr, XrmValuePtr);
Packit b099d7
static Boolean CvtStringToLineStyle(Display *, XrmValuePtr, Cardinal *, 
Packit b099d7
				       XrmValuePtr, XrmValuePtr);
Packit b099d7
Packit b099d7
static void ReleaseNodeGCs(Widget), GetNodeGCs(Widget);
Packit b099d7
static TreeConstraints GetNodeInfo(Widget);
Packit b099d7
static int GetExtraVertSpace(Widget);
Packit b099d7
static int GetExtraHorizSpace(Widget);
Packit b099d7
Packit b099d7
static void LineColorDefault(Widget, int, XrmValue *);
Packit b099d7
static void LineBackgroundColorDefault(Widget, int, XrmValue *);
Packit b099d7
static void HorizontalNodeSpaceDefault(Widget, int, XrmValue *);
Packit b099d7
static void VerticalNodeSpaceDefault(Widget, int, XrmValue *);
Packit b099d7
Packit b099d7
static void ChangeManaged(Widget), CalcMaxSize(Widget);
Packit b099d7
static void CalcLocations(Widget, Boolean);
Packit b099d7
static void LayoutChildren(Widget, Widget);
Packit b099d7
static Boolean GetNodeHeightAndWidth(Widget, TreeConstraints,
Packit b099d7
				     Cardinal *, Cardinal);
Packit b099d7
static void GetDesiredSize(Widget, Dimension *, Dimension *, Boolean);
Packit b099d7
Packit b099d7
static void _DrawLine(Widget, XRectangle *, TreeConstraints, TreeConstraints,
Packit b099d7
		      LadderPoint, LadderPoint *);
Packit b099d7
static void _PlaceNode(Widget, TreeConstraints);
Packit b099d7
static void _ResetPlacedFlag(TreeConstraints);
Packit b099d7
Packit b099d7
static void FindNodeLocations(Widget);
Packit b099d7
static void DrawTreeLine(Widget, XRectangle *, TreeConstraints);
Packit b099d7
static void RedrawTreeLines(Widget, XRectangle *);
Packit b099d7
Packit b099d7
static Boolean RequestNewSize(Widget);
Packit b099d7
Packit b099d7
static Bool CheckExpose(Display *, XEvent *, char *);
Packit b099d7
Packit b099d7
static Boolean LocInRect(XRectangle *, Widget, Position, Position);
Packit b099d7
static Boolean WidgetInRect(XRectangle *, Widget);
Packit b099d7
static Boolean CheckWidget(XRectangle *, TreeConstraints);
Packit b099d7
static void ProcessChildQueue(XmTreeWidget, XRectangle *);
Packit b099d7
static void MoveNode(XmTreeWidget, TreeConstraints, Position, Position,
Packit b099d7
		     Position, Position, Boolean);
Packit b099d7
static void ProcessNode(TreeConstraints);
Packit b099d7
static Boolean MoveNodesTimer(XtPointer);
Packit b099d7
static void UnmapNode(XmTreeWidget tw, TreeConstraints node);
Packit b099d7
static void UnmapAllExtraNodes(Widget w, HierarchyConstraints node);
Packit b099d7
Packit b099d7
static void LineStyle_confirm (Widget w, int value);
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	STATIC DECLARATIONS
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
static XtResource resources[] =
Packit b099d7
{
Packit b099d7
  {
Packit b099d7
    XmNconnectStyle, XmCConnectStyle, XmRXmConnectStyle,
Packit b099d7
    sizeof(XmTreeConnectStyle), XtOffsetOf(XmTreeRec, tree.connect_style),
Packit b099d7
    XmRImmediate, (XtPointer) XmTreeDirect
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNorientation, XmCOrientation, XmROrientation,
Packit b099d7
    sizeof(unsigned char), XtOffsetOf(XmTreeRec, tree.orientation),
Packit b099d7
    XmRImmediate, (XtPointer) XmHORIZONTAL
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNcompressStyle, XmCCompressStyle, XmRXmCompressStyle,
Packit b099d7
    sizeof(XmTreeCompressStyle), XtOffsetOf(XmTreeRec, tree.compress_style),
Packit b099d7
    XmRImmediate, (XtPointer) XmTreeCompressLeaves
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNverticalDelta, XmCVerticalDelta, XmRVerticalDimension,
Packit b099d7
    sizeof(Dimension), XtOffsetOf(XmTreeRec, tree.vertical_delta),
Packit b099d7
    XmRImmediate, (XtPointer) 30
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNhorizontalDelta, XmCHorizontalDelta, XmRHorizontalDimension,
Packit b099d7
    sizeof(Dimension), XtOffsetOf(XmTreeRec, tree.horizontal_delta),
Packit b099d7
    XmRImmediate, (XtPointer) 25
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNhorizontalNodeSpace, XmCDimension, XmRHorizontalDimension,
Packit b099d7
    sizeof(Dimension), XtOffsetOf(XmTreeRec, tree.h_node_space),
Packit b099d7
    XmRCallProc, (XtPointer) HorizontalNodeSpaceDefault
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNverticalNodeSpace, XmCDimension, XmRVerticalDimension,
Packit b099d7
    sizeof(Dimension), XtOffsetOf(XmTreeRec, tree.v_node_space),
Packit b099d7
    XmRCallProc, (XtPointer) VerticalNodeSpaceDefault
Packit b099d7
  }
Packit b099d7
};
Packit b099d7
Packit b099d7
static XmSyntheticResource get_resources[] =
Packit b099d7
{
Packit b099d7
  {
Packit b099d7
    XmNhorizontalNodeSpace, sizeof(Dimension),
Packit b099d7
    XtOffsetOf(XmTreeRec, tree.h_node_space),
Packit b099d7
    XmeFromHorizontalPixels, (XmImportProc) XmeToHorizontalPixels
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNverticalNodeSpace, sizeof(Dimension),
Packit b099d7
    XtOffsetOf(XmTreeRec, tree.v_node_space),
Packit b099d7
    XmeFromVerticalPixels, (XmImportProc) XmeToVerticalPixels
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNverticalDelta, sizeof(Dimension),
Packit b099d7
    XtOffsetOf(XmTreeRec, tree.vertical_delta),
Packit b099d7
    XmeFromVerticalPixels, (XmImportProc) XmeToVerticalPixels
Packit b099d7
  },
Packit b099d7
Packit b099d7
  {
Packit b099d7
    XmNhorizontalDelta, sizeof(Dimension),
Packit b099d7
    XtOffsetOf(XmTreeRec, tree.horizontal_delta),
Packit b099d7
    XmeFromHorizontalPixels, (XmImportProc) XmeToHorizontalPixels
Packit b099d7
  }
Packit b099d7
};
Packit b099d7
Packit b099d7
static XtResource constraints[] =
Packit b099d7
{
Packit b099d7
  {
Packit b099d7
    XmNopenClosePadding, XmCOpenClosePadding, XmRInt,
Packit b099d7
    sizeof(int), XtOffsetOf(XmTreeConstraintRec, tree.open_close_padding),
Packit b099d7
    XmRImmediate, (XtPointer) 0
Packit b099d7
  },
Packit b099d7
  
Packit b099d7
  {
Packit b099d7
    XmNlineColor, XmCForeground, XmRPixel,
Packit b099d7
    sizeof(Pixel), XtOffsetOf(XmTreeConstraintRec, tree.color),
Packit b099d7
    XmRCallProc, (XtPointer) LineColorDefault
Packit b099d7
  },
Packit b099d7
  
Packit b099d7
  {
Packit b099d7
    XmNlineBackgroundColor, XmCBackground, XmRPixel,
Packit b099d7
    sizeof(Pixel), XtOffsetOf(XmTreeConstraintRec, tree.background_color),
Packit b099d7
    XmRCallProc, (XtPointer) LineBackgroundColorDefault
Packit b099d7
  },
Packit b099d7
  
Packit b099d7
  {
Packit b099d7
    XmNlineWidth, XmCLineWidth, XmRInt,
Packit b099d7
    sizeof(int), XtOffsetOf(XmTreeConstraintRec, tree.line_width),
Packit b099d7
    XmRImmediate, (XtPointer) 0
Packit b099d7
  },
Packit b099d7
  
Packit b099d7
  {
Packit b099d7
    XmNlineStyle, XmCLineStyle, XmRXmLineStyle,
Packit b099d7
    sizeof(int), XtOffsetOf(XmTreeConstraintRec, tree.line_style),
Packit b099d7
    XmRImmediate, (XtPointer) LineSolid
Packit b099d7
  }
Packit b099d7
};
Packit b099d7
Packit b099d7
static XmSyntheticResource get_cons_resources[] =
Packit b099d7
{
Packit b099d7
  {
Packit b099d7
    XmNopenClosePadding, sizeof(int),
Packit b099d7
    XtOffsetOf(XmTreeConstraintRec, tree.open_close_padding),
Packit b099d7
    XmeFromHorizontalPixels, (XmImportProc) XmeToHorizontalPixels
Packit b099d7
  }
Packit b099d7
};
Packit b099d7
Packit b099d7
#undef offset
Packit b099d7
Packit b099d7
XmTreeClassRec xmTreeClassRec = {
Packit b099d7
  { /* core fields */
Packit b099d7
    /* superclass		*/	((WidgetClass) SUPERCLASS),
Packit b099d7
    /* class_name		*/	"XmTree",
Packit b099d7
    /* widget_size		*/	sizeof(XmTreeRec),
Packit b099d7
    /* class_initialize		*/	ClassInit,
Packit b099d7
    /* class_part_initialize	*/	ClassPartInitialize,
Packit b099d7
    /* class_inited		*/	FALSE,
Packit b099d7
    /* initialize		*/	Initialize,
Packit b099d7
    /* initialize_hook		*/	NULL,
Packit b099d7
    /* realize			*/	Realize,
Packit b099d7
    /* actions			*/	NULL,
Packit b099d7
    /* num_actions		*/	0,
Packit b099d7
    /* resources		*/	(XtResource*)resources,
Packit b099d7
    /* num_resources		*/	XtNumber(resources),
Packit b099d7
    /* xrm_class		*/	NULLQUARK,
Packit b099d7
    /* compress_motion		*/	TRUE,
Packit b099d7
    /* compress_exposure	*/	XtExposeCompressMultiple,
Packit b099d7
    /* compress_enterleave	*/	TRUE,
Packit b099d7
    /* visible_interest		*/	FALSE,
Packit b099d7
    /* destroy			*/	TreeDestroy,
Packit b099d7
    /* resize			*/	Resize,
Packit b099d7
    /* expose			*/	Redisplay,
Packit b099d7
    /* set_values		*/	SetValues,
Packit b099d7
    /* set_values_hook		*/	NULL,
Packit b099d7
    /* set_values_almost	*/	XtInheritSetValuesAlmost,
Packit b099d7
    /* get_values_hook		*/	NULL,
Packit b099d7
    /* accept_focus		*/	NULL,
Packit b099d7
    /* version			*/	XtVersion,
Packit b099d7
    /* callback_private		*/	NULL,
Packit b099d7
    /* tm_table			*/	XtInheritTranslations,
Packit b099d7
    /* query_geometry		*/	(XtGeometryHandler) QueryGeometry,
Packit b099d7
    /* display_accelerator	*/	XtInheritDisplayAccelerator,
Packit b099d7
    /* extension		*/	NULL
Packit b099d7
  },
Packit b099d7
   {		/* composite_class fields */
Packit b099d7
    /* geometry_manager   */      GeometryManager,
Packit b099d7
    /* change_managed     */      ChangeManaged,
Packit b099d7
    /* insert_child       */      XtInheritInsertChild,
Packit b099d7
    /* delete_child       */      XtInheritDeleteChild,
Packit b099d7
    /* extension          */      NULL,                                     
Packit b099d7
   },
Packit b099d7
   {		/* constraint_class fields */
Packit b099d7
    /* resource list        */         (XtResource*)constraints,
Packit b099d7
    /* num resources        */         XtNumber(constraints),
Packit b099d7
    /* constraint size      */         sizeof(XmTreeConstraintRec),
Packit b099d7
    /* init proc            */         ConstraintInitialize,
Packit b099d7
    /* destroy proc         */         ConstraintDestroy,
Packit b099d7
    /* set values proc      */         ConstraintSetValues,
Packit b099d7
    /* extension            */         NULL, 
Packit b099d7
   },
Packit b099d7
   {		/* manager_class fields */
Packit b099d7
    /* default translations   */      XtInheritTranslations,	
Packit b099d7
    /* syn_resources          */      get_resources,
Packit b099d7
    /* num_syn_resources      */      XtNumber(get_resources),
Packit b099d7
    /* syn_cont_resources     */      get_cons_resources,
Packit b099d7
    /* num_syn_cont_resources */      XtNumber(get_cons_resources),
Packit b099d7
    /* parent_process         */      XmInheritParentProcess,
Packit b099d7
    /* extension	      */      NULL,	
Packit b099d7
   },
Packit b099d7
   { /* Hierarchy fields */
Packit b099d7
      XtInheritChangeNodeState,	/* The function for changing the node state. */
Packit b099d7
      XtInheritMapNode,			/* Maps a given node. */
Packit b099d7
      XtInheritUnmapNode,		/* Unmaps a given node. */
Packit b099d7
      UnmapAllExtraNodes,		/* Unmaps all extra nodes. */
Packit b099d7
      XtInheritBuildNodeTable,		/* Builds up the node table. */
Packit b099d7
      XtInheritResetOpenCloseButton, 	/* Resets the the o/c button. */
Packit b099d7
      ToggleNodeState,		/* Called to toggle the state of node. */
Packit b099d7
      NULL,			/* extension          */
Packit b099d7
   },
Packit b099d7
   { /* Tree fields */
Packit b099d7
      NULL                      /* extension    */
Packit b099d7
   }
Packit b099d7
};
Packit b099d7
Packit b099d7
WidgetClass xmTreeWidgetClass = (WidgetClass) &xmTreeClassRec;
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
*	STATIC CODE
Packit b099d7
*************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: ClassInit
Packit b099d7
 *	Description:   Called to initialize information specific
Packit b099d7
 *                     to this widget class.
Packit b099d7
 *	Arguments:     none.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void 
Packit b099d7
ClassInit(void)
Packit b099d7
{
Packit b099d7
    XmTreeClassRec* wc = &xmTreeClassRec;
Packit b099d7
Packit b099d7
    XtSetTypeConverter(XmRString, XmRXmConnectStyle,
Packit b099d7
		       (XtTypeConverter) CvtStringToConnectStyle,
Packit b099d7
		       NULL, (Cardinal) 0, XtCacheAll, (XtDestructor) NULL);
Packit b099d7
    XtSetTypeConverter(XmRString, XmRXmCompressStyle,
Packit b099d7
		       (XtTypeConverter) CvtStringToCompressStyle,
Packit b099d7
		       NULL, (Cardinal) 0, XtCacheAll, (XtDestructor) NULL);
Packit b099d7
    XtSetTypeConverter(XmRString, XmRXmLineStyle,
Packit b099d7
		       (XtTypeConverter) CvtStringToLineStyle,
Packit b099d7
		       NULL, (Cardinal) 0, XtCacheNone, (XtDestructor) NULL);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * ClassPartInitialize sets up the fast subclassing for the widget.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
#ifdef _NO_PROTO
Packit b099d7
ClassPartInitialize(w_class)
Packit b099d7
        WidgetClass w_class ;
Packit b099d7
#else
Packit b099d7
ClassPartInitialize(WidgetClass w_class)
Packit b099d7
#endif /* _NO_PROTO */
Packit b099d7
{
Packit b099d7
    _XmFastSubclassInit (w_class, XmTREE_BIT);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*	Function Name: Initialize
Packit b099d7
 *	Description:   Called to initialize information specific
Packit b099d7
 *                     to this widget.
Packit b099d7
 *	Arguments:     req - what was originally requested.
Packit b099d7
 *                     set - what will be created (our superclassed have
Packit b099d7
 *                           already mucked with this)
Packit b099d7
 *                     args, num_args - The arguments passed to 
Packit b099d7
 *                                      the creation call.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void 
Packit b099d7
Initialize(Widget req, Widget set, ArgList args, Cardinal * num_args)
Packit b099d7
{
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) set;
Packit b099d7
    TreeConstraints top_node;
Packit b099d7
Packit b099d7
    top_node = ((TreeConstraints) 
Packit b099d7
		XtRealloc((XtPointer) XmHierarchy_top_node(tw),
Packit b099d7
			  sizeof(TreeConstraintRec)));
Packit b099d7
Packit b099d7
    XmHierarchy_top_node(tw) = (HierarchyConstraints) top_node;
Packit b099d7
Packit b099d7
    XmTree_ul_point(tw).x = XmTree_ul_point(tw).y = 0;
Packit b099d7
    XmTree_lr_point(tw).x = XmTree_lr_point(tw).y = 0;
Packit b099d7
    
Packit b099d7
    XmTreeC_box_x(top_node) = XmTreeC_box_y(top_node) = 0;
Packit b099d7
    XmTreeC_bb_width(top_node) = XmTreeC_bb_height(top_node) = 0;
Packit b099d7
    XmTreeC_placed(top_node) = False;
Packit b099d7
Packit b099d7
    XmTree_child_op_list(tw) = _XmListInit();
Packit b099d7
Packit b099d7
    /* 
Packit b099d7
     * Set the initial values for XmTreeC_max_width(tw) and XmTreeC_max_height(tw).
Packit b099d7
     */
Packit b099d7
    
Packit b099d7
    CalcMaxSize(set);    
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: Realize
Packit b099d7
 *	Description:   Called to realize this widget.
Packit b099d7
 *	Arguments:     w - Widget to realize.
Packit b099d7
 *                     valueMask, attributes - attributes to use when creating
Packit b099d7
 *                     this widget's window.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 *
Packit b099d7
 * This overrides the Manager's frobbing with various values.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void 
Packit b099d7
Realize(Widget w, Mask *valueMask, XSetWindowAttributes * attributes)
Packit b099d7
{
Packit b099d7
   XtCreateWindow (w, InputOutput, CopyFromParent, *valueMask, attributes);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: Redisplay
Packit b099d7
 *	Description:   This function redraws the tree lines.
Packit b099d7
 *	Arguments:     w - the Tree widget.
Packit b099d7
 *                     event - event that caused the exposure.
Packit b099d7
 *                     region - the region containing all the exposures.
Packit b099d7
 *	Returns:       none
Packit b099d7
 */
Packit b099d7
Packit b099d7
typedef struct _RedispInfo {
Packit b099d7
    Window window;
Packit b099d7
    Boolean found;
Packit b099d7
} RedispInfo;
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void
Packit b099d7
Redisplay(Widget w, XEvent * event, Region region)
Packit b099d7
{
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) w;
Packit b099d7
    XEvent junk;
Packit b099d7
    RedispInfo info;
Packit b099d7
    int lrx, lry;		/* local variables fro lower left corner. */
Packit b099d7
Packit b099d7
    XmDropSiteStartUpdate(w);
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Make sure that there are not more expose events pending in the queue
Packit b099d7
     * since only one is required to paint the tree lines.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    info.window = XtWindow(w);
Packit b099d7
    info.found = False;
Packit b099d7
    XCheckIfEvent(XtDisplay(w), &junk, CheckExpose, (char *) &info;;
Packit b099d7
Packit b099d7
    /* 
Packit b099d7
     * Compute the maximum bounding rectangle for all expose events
Packit b099d7
     * that have yet to be processed.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (event->xexpose.x < XmTree_ul_point(tw).x) 
Packit b099d7
	XmTree_ul_point(tw).x = event->xexpose.x;
Packit b099d7
    if (event->xexpose.y < XmTree_ul_point(tw).y) 
Packit b099d7
	XmTree_ul_point(tw).y = event->xexpose.y;
Packit b099d7
Packit b099d7
    lrx = event->xexpose.x + event->xexpose.width;
Packit b099d7
    lry = event->xexpose.y + event->xexpose.height;
Packit b099d7
Packit b099d7
    if (lrx > XmTree_lr_point(tw).x) 
Packit b099d7
	XmTree_lr_point(tw).x = lrx;
Packit b099d7
    if (lry > XmTree_lr_point(tw).y) 
Packit b099d7
	XmTree_lr_point(tw).y = lry;
Packit b099d7
Packit b099d7
    if (!info.found) {	/* No more expose events waiting - process these. */
Packit b099d7
	XRectangle rect;
Packit b099d7
Packit b099d7
	rect.x = XmTree_ul_point(tw).x;
Packit b099d7
	rect.y = XmTree_ul_point(tw).y;
Packit b099d7
	rect.width = XmTree_lr_point(tw).x - XmTree_ul_point(tw).x;
Packit b099d7
	rect.height = XmTree_lr_point(tw).y - XmTree_ul_point(tw).y;
Packit b099d7
Packit b099d7
	ProcessChildQueue((XmTreeWidget) w, &rect);
Packit b099d7
	RedrawTreeLines(w, &rect);
Packit b099d7
	
Packit b099d7
	/*
Packit b099d7
	 * Reset upper right and lower left points.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	XmTree_ul_point(tw).x = w->core.width;
Packit b099d7
	XmTree_ul_point(tw).y = w->core.height;
Packit b099d7
	XmTree_lr_point(tw).x = XmTree_lr_point(tw).y = 0;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XmDropSiteEndUpdate(w);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: CheckExpose
Packit b099d7
 *	Description: Checks to see if there is an expose event on the queue.
Packit b099d7
 *	Arguments: disp - the X Display.
Packit b099d7
 *                 event - the event to check for.
Packit b099d7
 *                 info_ptr - a pointer to the redispInfo.
Packit b099d7
 *	Returns: Always False.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static Bool
Packit b099d7
CheckExpose(Display *disp, XEvent *event, char *info_ptr)
Packit b099d7
{
Packit b099d7
    RedispInfo *info = (RedispInfo *) info_ptr;
Packit b099d7
Packit b099d7
    if (info->found || event->xany.type != Expose)
Packit b099d7
	return(False);
Packit b099d7
Packit b099d7
    if (event->xexpose.window == info->window)
Packit b099d7
	info->found = True;
Packit b099d7
Packit b099d7
    return(False);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: Resize
Packit b099d7
 *	Description:   Called when this widget has been resized.
Packit b099d7
 *	Arguments:     w - Extended List Widget to resize.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void 
Packit b099d7
Resize(Widget w)
Packit b099d7
{
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) w;
Packit b099d7
Packit b099d7
    if (XmHierarchy_refigure_mode(tw)) {
Packit b099d7
	LayoutChildren(w, NULL);
Packit b099d7
	if (XtIsRealized((Widget)tw)) {
Packit b099d7
	    XClearArea(XtDisplay(tw), XtWindow(tw),
Packit b099d7
		       0, 0, tw->core.width, tw->core.height, True);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: QueryGeometry
Packit b099d7
 *	Description:   Called when my parent wants to know what size
Packit b099d7
 *                     I would like to be.
Packit b099d7
 *	Arguments:     w - the drt widget.
Packit b099d7
 *                     indended - constriants imposed by the parent.
Packit b099d7
 *                     preferred - what I would like.
Packit b099d7
 *	Returns:       See Xt Manual.
Packit b099d7
 */
Packit b099d7
    
Packit b099d7
static XtGeometryResult 
Packit b099d7
QueryGeometry(Widget w,XtWidgetGeometry *intended, XtWidgetGeometry *preferred)
Packit b099d7
{
Packit b099d7
    GetDesiredSize(w, &(preferred->width), &(preferred->height), True);
Packit b099d7
    return(_XmHWQuery(w, intended, preferred));
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: SetValues
Packit b099d7
 *	Description:   Called a resources is changed.
Packit b099d7
 *	Arguments:     current - the current (old) widget values.
Packit b099d7
 *                     request - before superclassed have changed things.
Packit b099d7
 *                     set - what will acutally be the new values. 
Packit b099d7
 *                     args, num_args - the arguments in the list.
Packit b099d7
 *	Returns:       none
Packit b099d7
 */
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static Boolean 
Packit b099d7
SetValues(Widget current, Widget request, Widget set,
Packit b099d7
	  ArgList args, Cardinal * num_args)
Packit b099d7
{
Packit b099d7
    XmTreeWidget c_tree = (XmTreeWidget) current;
Packit b099d7
    XmTreeWidget tree = (XmTreeWidget) set;
Packit b099d7
    Boolean redisplay = False;
Packit b099d7
    Boolean layout = False;
Packit b099d7
Packit b099d7
    if ((XmHierarchy_v_margin(c_tree) != XmHierarchy_v_margin(tree)) ||
Packit b099d7
	(XmHierarchy_h_margin(c_tree) != XmHierarchy_h_margin(tree)) ||
Packit b099d7
	(XmTree_orientation(c_tree) != XmTree_orientation(tree)) ||
Packit b099d7
	((XmTree_compress_style(c_tree) != XmTree_compress_style(tree)) &&
Packit b099d7
         (XmTree_orientation(tree) == XmVERTICAL))                  ||
Packit b099d7
	(XmTree_horizontal_delta(c_tree) != XmTree_horizontal_delta(tree)) ||
Packit b099d7
	(XmTree_vertical_delta(c_tree) != XmTree_vertical_delta(tree)) ||
Packit b099d7
	(XmTree_v_node_space(c_tree) != XmTree_v_node_space(tree)) ||
Packit b099d7
	(XmTree_h_node_space(c_tree) != XmTree_h_node_space(tree)))
Packit b099d7
    {
Packit b099d7
	layout = redisplay = True;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (XmTree_connect_style(c_tree) != XmTree_connect_style(tree))
Packit b099d7
	redisplay = True;
Packit b099d7
Packit b099d7
    if (XmHierarchy_refigure_mode(c_tree) != XmHierarchy_refigure_mode(tree))
Packit b099d7
	layout = redisplay = XmHierarchy_refigure_mode(tree);
Packit b099d7
Packit b099d7
    if (layout && XmHierarchy_refigure_mode(tree)) {
Packit b099d7
	CalcLocations(set, False);
Packit b099d7
	LayoutChildren(set, NULL);
Packit b099d7
Packit b099d7
	GetDesiredSize(set, &(set->core.width), &(set->core.height), False);
Packit b099d7
	redisplay = True;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    return(redisplay);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*    Function Name: Destroy
Packit b099d7
 *    Description:   Destroys all data allocated by the widget
Packit b099d7
 *    Arguments:     w - the widget.
Packit b099d7
 *    Returns:       none.
Packit b099d7
 */
Packit b099d7
static void TreeDestroy (Widget widget)
Packit b099d7
{
Packit b099d7
  XmTreeWidget tree = (XmTreeWidget) widget;
Packit b099d7
Packit b099d7
    _XmListFree(XmTree_child_op_list(tree)); 
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 *  Composite Widget class procedures.
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: ChangeManaged
Packit b099d7
 *	Description:   When a management change has occured...
Packit b099d7
 *	Arguments:     w - the icon box widget.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
ChangeManaged(Widget w)
Packit b099d7
{
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) w;
Packit b099d7
Packit b099d7
    if (XmHierarchy_refigure_mode(tw)) {
Packit b099d7
	CalcLocations(w, True);
Packit b099d7
	LayoutChildren(w, NULL);
Packit b099d7
	if (XtIsRealized((Widget)tw)) {
Packit b099d7
	    XClearArea(XtDisplay(tw), XtWindow(tw),
Packit b099d7
		       0, 0, tw->core.width, tw->core.height, True);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
   XmeNavigChangeManaged(w);	/* for Motif navigation */
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: GeometryManager
Packit b099d7
 *	Description:   handles requests from children for a size change.
Packit b099d7
 *	Arguments:     child - the child to change.
Packit b099d7
 *                     request - the geometry that the child wants.
Packit b099d7
 *                     return - what we will allow if this is an almost.
Packit b099d7
 *	Returns:       status.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static XtGeometryResult
Packit b099d7
GeometryManager(Widget w, XtWidgetGeometry * request, 
Packit b099d7
		XtWidgetGeometry * result)
Packit b099d7
{
Packit b099d7
    Widget tw = XtParent(w);
Packit b099d7
Packit b099d7
    if (!(request->request_mode & (CWWidth | CWHeight | CWBorderWidth)))
Packit b099d7
	return(XtGeometryNo);
Packit b099d7
    
Packit b099d7
    if (!(request->request_mode & CWWidth)) {
Packit b099d7
	request->width = w->core.width;
Packit b099d7
	request->request_mode |= CWWidth;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (!(request->request_mode & CWBorderWidth)) {
Packit b099d7
	request->border_width = w->core.border_width;
Packit b099d7
	request->request_mode |= CWBorderWidth;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (!(request->request_mode & CWHeight)) {
Packit b099d7
	request->height = w->core.height;
Packit b099d7
	request->request_mode |= CWHeight;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (request->request_mode & (CWX | CWY | CWStackMode | CWSibling)) {
Packit b099d7
	*result = *request;
Packit b099d7
	result->request_mode &= ~(CWX | CWY | CWStackMode | CWSibling);
Packit b099d7
	return(XtGeometryAlmost);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Any width or height request is allowed, but others will be disallowed
Packit b099d7
     * or result in an almost that states only the width and height can
Packit b099d7
     * change. 
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (request->request_mode & XtCWQueryOnly) 
Packit b099d7
	return(XtGeometryYes);
Packit b099d7
	
Packit b099d7
    /*
Packit b099d7
     * A real allowed request, make the change.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    _XmResizeWidget(w, request->width, request->height, request->border_width);
Packit b099d7
Packit b099d7
    if (XmHierarchy_refigure_mode((XmTreeWidget) tw)) {
Packit b099d7
	CalcLocations(tw, True);
Packit b099d7
	LayoutChildren(tw, w);
Packit b099d7
	if (XtIsRealized(tw)) {
Packit b099d7
	    XClearArea(XtDisplay(tw), XtWindow(tw),
Packit b099d7
		       0, 0, tw->core.width, tw->core.height, True);
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    return(XtGeometryYes);
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 * 
Packit b099d7
 * Constraint widget class procedures.
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: ConstraintInitialize
Packit b099d7
 *	Description:   Called when a childs constriaints need initializing.
Packit b099d7
 *	Arguments:     req - the widget being requested.
Packit b099d7
 *                     set - what this will become.
Packit b099d7
 *                     args, num_args - the argument list.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void
Packit b099d7
ConstraintInitialize(Widget req, Widget set, ArgList args, Cardinal * num_args)
Packit b099d7
{
Packit b099d7
    TreeConstraints node = GetNodeInfo(set);
Packit b099d7
Packit b099d7
    XmTreeC_box_x(node) = XmTreeC_box_y(node) = 0;
Packit b099d7
    XmTreeC_bb_width(node) = XmTreeC_bb_height(node) = 0;
Packit b099d7
    XmTreeC_placed(node) = False;
Packit b099d7
    XmTreeC_is_compressed(node) = False;
Packit b099d7
Packit b099d7
    LineStyle_confirm(set, LineSolid);
Packit b099d7
    
Packit b099d7
    if (XmHierarchyC_state(node) != XmNotInHierarchy)
Packit b099d7
	GetNodeGCs(set);
Packit b099d7
    else
Packit b099d7
 	XmTreeC_gc(node) = None;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: ConstraintDestroy
Packit b099d7
 *	Description:   Destroys all data allocated by the constraint 
Packit b099d7
 *                     record.
Packit b099d7
 *	Arguments:     w - the widget.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 *
Packit b099d7
 * Removes the destroyed children from the list of children that still
Packit b099d7
 * need to be moved.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
ConstraintDestroy(Widget w)
Packit b099d7
{
Packit b099d7
    TreeConstraints node = GetNodeInfo(w);
Packit b099d7
    XmListElem *elem, *next;
Packit b099d7
    XmTreeWidget tw;
Packit b099d7
Packit b099d7
    if (XmHierarchyC_state(node) == XmNotInHierarchy) 
Packit b099d7
    {
Packit b099d7
      return;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    tw = (XmTreeWidget) XtParent(w);
Packit b099d7
    elem = XmListFirst(XmTree_child_op_list(tw)); 
Packit b099d7
    while(elem != NULL) {
Packit b099d7
	TreeConstraints info = (TreeConstraints) XmListElemData(elem);
Packit b099d7
Packit b099d7
	next = XmListElemNext(elem);
Packit b099d7
Packit b099d7
	if (XmHierarchyC_widget(info) == w) {
Packit b099d7
	    /*
Packit b099d7
	     * Each widget will only be in the list once.
Packit b099d7
	     */
Packit b099d7
Packit b099d7
	    _XmListRemove(XmTree_child_op_list(tw), elem);
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	elem = next;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    ReleaseNodeGCs(w);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: GetNodeGCs(node)
Packit b099d7
 *	Description: Gets the gc's associated with a tree node.
Packit b099d7
 *	Arguments: w - the child who's gc we are getting.
Packit b099d7
 *	Returns: none
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
GetNodeGCs(Widget w)
Packit b099d7
{
Packit b099d7
    XtGCMask mask;
Packit b099d7
    XGCValues values;
Packit b099d7
    TreeConstraints node = GetNodeInfo(w);
Packit b099d7
Packit b099d7
    mask = GCForeground | GCLineWidth | GCLineStyle | GCBackground;
Packit b099d7
    values.foreground = XmTreeC_color(node);
Packit b099d7
    values.background = XmTreeC_background_color(node);
Packit b099d7
    values.line_width = XmTreeC_line_width(node);
Packit b099d7
    values.line_style = XmTreeC_line_style(node);
Packit b099d7
    XmTreeC_gc(node) = XtGetGC(w, mask, &values);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: ReleaseNodeGCs(node)
Packit b099d7
 *	Description: Releases the gc's associated with a tree node.
Packit b099d7
 *	Arguments: w - the child who's gc we are releasing
Packit b099d7
 *	Returns: none
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
ReleaseNodeGCs(Widget w)
Packit b099d7
{
Packit b099d7
    TreeConstraints node = GetNodeInfo(w);
Packit b099d7
Packit b099d7
    if (XmTreeC_gc(node) != None)
Packit b099d7
	XtReleaseGC(w, XmTreeC_gc(node));
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: ConstraintSetValues
Packit b099d7
 *	Description:   Called a constraint is changed on my children.
Packit b099d7
 *	Arguments:     current - the current (old) widget values.
Packit b099d7
 *                     request - before superclassed have changed things.
Packit b099d7
 *                     set - what will acutally be the new values. 
Packit b099d7
 *                     args, num_args - the arguments in the list.
Packit b099d7
 *	Returns:       none
Packit b099d7
 */
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static Boolean 
Packit b099d7
ConstraintSetValues(Widget current, Widget request, Widget set,
Packit b099d7
		    ArgList args, Cardinal * num_args)
Packit b099d7
{
Packit b099d7
    Widget tw = XtParent(set);
Packit b099d7
    TreeConstraints set_node = GetNodeInfo(set);
Packit b099d7
    TreeConstraints old_node = GetNodeInfo(current);
Packit b099d7
    Boolean redisplay = False;
Packit b099d7
    Boolean insert_change = False;
Packit b099d7
    int i;
Packit b099d7
Packit b099d7
    for (i = 0; i < *num_args; i++) 
Packit b099d7
	if (streq(args[i].name, XmNinsertBefore)) {
Packit b099d7
	    insert_change = True;
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
Packit b099d7
    if ((XmTreeC_color(set_node) != XmTreeC_color(old_node)) ||
Packit b099d7
    	(XmTreeC_background_color(set_node) != XmTreeC_background_color(old_node)) ||
Packit b099d7
    	(XmTreeC_line_width(set_node) != XmTreeC_line_width(old_node)) ||
Packit b099d7
    	(XmTreeC_line_style(set_node) != XmTreeC_line_style(old_node)))
Packit b099d7
    {
Packit b099d7
	LineStyle_confirm(set, XmTreeC_line_style(old_node));
Packit b099d7
	ReleaseNodeGCs(current);
Packit b099d7
	GetNodeGCs(set);
Packit b099d7
	redisplay = True;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Nothing below here needs to be done before we are realized.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (!XtIsRealized(set))
Packit b099d7
	return(False);
Packit b099d7
Packit b099d7
    if ((XmHierarchyC_parent(set_node) != XmHierarchyC_parent(old_node)) ||
Packit b099d7
	(XmHierarchyC_state(set_node) != XmHierarchyC_state(old_node)) ||
Packit b099d7
	(insert_change) || (XmTreeC_open_close_padding(set_node) != 
Packit b099d7
			    XmTreeC_open_close_padding(old_node)))
Packit b099d7
    {
Packit b099d7
	 /*
Packit b099d7
	  * Other operations have already been performed by my superclass. 
Packit b099d7
	  */
Packit b099d7
Packit b099d7
        if (XmHierarchy_refigure_mode((XmTreeWidget)tw)) {
Packit b099d7
	    CalcLocations(tw, True);
Packit b099d7
	    LayoutChildren(tw, NULL);
Packit b099d7
	    redisplay = True;
Packit b099d7
	}
Packit b099d7
	 
Packit b099d7
	 /*
Packit b099d7
	  * Since Layout children has (possibily) moved this widget
Packit b099d7
	  * to a new location.  The current state of the widget
Packit b099d7
	  * must be updated so that neither the intrinsics nor
Packit b099d7
	  * any sub-classes of this widget attempt to move it
Packit b099d7
	  * to the new location, since it is already there.
Packit b099d7
	  */
Packit b099d7
Packit b099d7
	 current->core.x = set->core.x;
Packit b099d7
	 current->core.y = set->core.y;
Packit b099d7
Packit b099d7
	 /*
Packit b099d7
	  * Since redisplay redraws the child, not the Tree widget we
Packit b099d7
	  * need to do the equilivent of a redisplay here.
Packit b099d7
	  */
Packit b099d7
Packit b099d7
	 redisplay = True;
Packit b099d7
     }
Packit b099d7
Packit b099d7
    if (XtIsRealized(tw) && redisplay && 
Packit b099d7
	(XmHierarchy_refigure_mode((XmTreeWidget)tw)))
Packit b099d7
    {
Packit b099d7
	XClearArea(XtDisplay(tw), XtWindow(tw),
Packit b099d7
		   0, 0, tw->core.width, tw->core.height, True);
Packit b099d7
    }
Packit b099d7
	
Packit b099d7
    return(False);   
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 * Hierarchy widget class proceedures.
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: ToggleNodeState
Packit b099d7
 *	Description:   Toggles the open/close state of a toggle button.
Packit b099d7
 *	Arguments:     w - the command button that activated this.
Packit b099d7
 *                     node_ptr - a pointer to the node info.
Packit b099d7
 *                     call_data - UNUSED.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void
Packit b099d7
ToggleNodeState(Widget w, XtPointer node_ptr, XtPointer call_data)
Packit b099d7
{
Packit b099d7
    Widget tw = XtParent(w);
Packit b099d7
    XtCallbackProc toggle_node_state;
Packit b099d7
    
Packit b099d7
    _XmProcessLock();
Packit b099d7
    toggle_node_state = (SUPERCLASS->hierarchy_class.toggle_node_state);
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
Packit b099d7
    (*toggle_node_state)(w, node_ptr, call_data);
Packit b099d7
    
Packit b099d7
    CalcLocations(tw, True);
Packit b099d7
    LayoutChildren(tw, NULL);
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Could check for a size change and abort if we really wanted
Packit b099d7
     * to be clever.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (XtIsRealized(tw)) {
Packit b099d7
	XClearArea(XtDisplay(tw), XtWindow(tw),
Packit b099d7
		   0, 0, tw->core.width, tw->core.height, True);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 * Type Converters.
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: CvtStringToConnectStyle
Packit b099d7
 *	Description:   Converts a string to a connect style
Packit b099d7
 *	Arguments:     dpy - the X Display.
Packit b099d7
 *                     args, num_args - *** NOT USED ***
Packit b099d7
 *                     fromVal - contains the string to convert.
Packit b099d7
 *                     toVal - contains the converted node state.
Packit b099d7
 *	Returns:       True if the SetValues succeeds.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Boolean
Packit b099d7
CvtStringToConnectStyle(Display * dpy, XrmValuePtr args, Cardinal *num_args, 
Packit b099d7
			XrmValuePtr fromVal, XrmValuePtr toVal)
Packit b099d7
{
Packit b099d7
    static XmTreeConnectStyle connect;
Packit b099d7
    static XrmQuark XtQELadder;
Packit b099d7
    static XrmQuark XtQEDirect;
Packit b099d7
    static Boolean haveQuarks = FALSE;
Packit b099d7
    XrmQuark q;
Packit b099d7
    char lowerName[BUFSIZ];
Packit b099d7
    
Packit b099d7
    if (!haveQuarks) {
Packit b099d7
	XtQELadder = XrmStringToQuark("ladder");
Packit b099d7
	XtQEDirect = XrmStringToQuark("direct");
Packit b099d7
	haveQuarks = TRUE;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    XmCopyISOLatin1Lowered(lowerName, (char *) fromVal->addr);
Packit b099d7
    q = XrmStringToQuark(lowerName);
Packit b099d7
    
Packit b099d7
    if ( (q == XtQELadder) || streq(lowerName,"treeladder") )
Packit b099d7
	connect = XmTreeLadder;
Packit b099d7
    else if ( (q == XtQEDirect) || streq(lowerName,"treedirect") )
Packit b099d7
	connect = XmTreeDirect;
Packit b099d7
    else {
Packit b099d7
	XtDisplayStringConversionWarning(dpy,fromVal->addr, XmRXmConnectStyle);
Packit b099d7
	return(FALSE);		/* Conversion failed. */
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (toVal->addr == NULL) {
Packit b099d7
	toVal->size = sizeof(XmTreeConnectStyle);
Packit b099d7
	toVal->addr = (XtPointer) &connect;
Packit b099d7
	return(TRUE);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (toVal->size >= sizeof(XmTreeConnectStyle)) {
Packit b099d7
	XmTreeConnectStyle *loc = (XmTreeConnectStyle *)toVal->addr;
Packit b099d7
	
Packit b099d7
	*loc = connect;
Packit b099d7
	return(TRUE);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    toVal->size = sizeof(XmTreeConnectStyle);
Packit b099d7
    return(FALSE);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*      Function Name: CvtStringToCompressStyle
Packit b099d7
 *      Description:   Converts a string to a compress style
Packit b099d7
 *      Arguments:     dpy - the X Display.
Packit b099d7
 *                     args, num_args - *** NOT USED ***
Packit b099d7
 *                     fromVal - contains the string to convert.
Packit b099d7
 *                     toVal - contains the converted value
Packit b099d7
 *      Returns:       True if the SetValues succeeds.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static Boolean
Packit b099d7
CvtStringToCompressStyle(Display * dpy, XrmValuePtr args, Cardinal *num_args,
Packit b099d7
                        XrmValuePtr fromVal, XrmValuePtr toVal)
Packit b099d7
{
Packit b099d7
    static XmTreeCompressStyle compress;
Packit b099d7
    static XrmQuark XtQECompressNone;
Packit b099d7
    static XrmQuark XtQECompressLeaves;
Packit b099d7
    static XrmQuark XtQECompressAll;
Packit b099d7
    static Boolean haveQuarks = FALSE;
Packit b099d7
    XrmQuark q;
Packit b099d7
    char lowerName[BUFSIZ];
Packit b099d7
Packit b099d7
    if (!haveQuarks) {
Packit b099d7
        XtQECompressNone = XrmStringToQuark("compressnone");
Packit b099d7
        XtQECompressLeaves = XrmStringToQuark("compressleaves");
Packit b099d7
        XtQECompressAll = XrmStringToQuark("compressall");
Packit b099d7
        haveQuarks = TRUE;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XmCopyISOLatin1Lowered(lowerName, (char *) fromVal->addr);
Packit b099d7
    q = XrmStringToQuark(lowerName);
Packit b099d7
   
Packit b099d7
    if ((q == XtQECompressNone) || streq(lowerName,"none") || streq(lowerName,"treecompressnone") )
Packit b099d7
        compress = XmTreeCompressNone;
Packit b099d7
    else if ((q == XtQECompressLeaves) || streq(lowerName,"leaves") || streq(lowerName,"treecompressleaves") )
Packit b099d7
        compress = XmTreeCompressLeaves;
Packit b099d7
    else if ((q == XtQECompressAll) || streq(lowerName,"all") || streq(lowerName,"treecompressall") )
Packit b099d7
        compress = XmTreeCompressAll;
Packit b099d7
    else {
Packit b099d7
        XtDisplayStringConversionWarning(dpy,fromVal->addr, XmRXmCompressStyle);
Packit b099d7
        return(FALSE);          /* Conversion failed. */
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (toVal->addr == NULL) {
Packit b099d7
        toVal->size = sizeof(XmTreeCompressStyle);
Packit b099d7
        toVal->addr = (XtPointer) &compress;
Packit b099d7
        return(TRUE);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (toVal->size >= sizeof(XmTreeCompressStyle)) {
Packit b099d7
        XmTreeCompressStyle *loc = (XmTreeCompressStyle *)toVal->addr;
Packit b099d7
Packit b099d7
        *loc = compress;
Packit b099d7
        return(TRUE);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    toVal->size = sizeof(XmTreeCompressStyle);
Packit b099d7
    return(FALSE);
Packit b099d7
}
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static Boolean
Packit b099d7
CvtStringToLineStyle(Display * dpy, XrmValuePtr args, Cardinal *num_args, 
Packit b099d7
			XrmValuePtr fromVal, XrmValuePtr toVal)
Packit b099d7
{
Packit b099d7
    static int lineStyle = LineSolid;
Packit b099d7
    char lowerName[BUFSIZ];
Packit b099d7
    
Packit b099d7
    XmCopyISOLatin1Lowered(lowerName, (char *) fromVal->addr);
Packit b099d7
    
Packit b099d7
    if ( streq(lowerName, "linesolid") || streq(lowerName,"solid") )
Packit b099d7
	lineStyle = LineSolid;
Packit b099d7
    else if ( streq(lowerName, "lineonoffdash") || streq(lowerName,"onoffdash") )
Packit b099d7
	lineStyle = LineOnOffDash;
Packit b099d7
    else if ( streq(lowerName, "linedoubledash") || streq(lowerName,"doubledash") )
Packit b099d7
	lineStyle = LineDoubleDash;
Packit b099d7
    else {
Packit b099d7
	XtDisplayStringConversionWarning(dpy,fromVal->addr, XmRXmLineStyle);
Packit b099d7
	return(FALSE);		/* Conversion failed. */
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (toVal->addr == NULL) {
Packit b099d7
	toVal->size = sizeof(int);
Packit b099d7
	toVal->addr = (XtPointer) &lineStyle;
Packit b099d7
	return(TRUE);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (toVal->size >= sizeof(int)) {
Packit b099d7
	int *loc = (int*)toVal->addr;
Packit b099d7
	
Packit b099d7
	*loc = lineStyle;
Packit b099d7
	return(TRUE);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    toVal->size = sizeof(int);
Packit b099d7
    return(FALSE);
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 * Actions and Callbacks.
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 * Internal routines.
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: HorizontalNodeSpaceDefault
Packit b099d7
 *	Description: determines the default value for the
Packit b099d7
 *                 XmNhorizontalNodeSpace resource based on
Packit b099d7
 *                 the orientation.
Packit b099d7
 *	Arguments: w - the tree widget
Packit b099d7
 *                 offset - offset of the field in the widget record.
Packit b099d7
 *                 value - resource descriptor to return.
Packit b099d7
 *	Returns: none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void 
Packit b099d7
HorizontalNodeSpaceDefault(Widget widget, int offset, XrmValue *value)
Packit b099d7
{
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) widget;
Packit b099d7
    static Dimension default_val;
Packit b099d7
Packit b099d7
    if (XmTree_orientation(tw) == XmVERTICAL)
Packit b099d7
        default_val = 2;
Packit b099d7
    else
Packit b099d7
        default_val = 20;
Packit b099d7
Packit b099d7
    value->addr = (XtPointer) &default_val;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: VerticalNodeSpaceDefault
Packit b099d7
 *	Description: determines the default value for the
Packit b099d7
 *                 XmNverticalNodeSpace resource based on
Packit b099d7
 *                 the orientation.
Packit b099d7
 *	Arguments: w - the tree widget
Packit b099d7
 *                 offset - offset of the field in the widget record.
Packit b099d7
 *                 value - resource descriptor to return.
Packit b099d7
 *	Returns: none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void 
Packit b099d7
VerticalNodeSpaceDefault(Widget widget, int offset, XrmValue *value)
Packit b099d7
{
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) widget;
Packit b099d7
    static Dimension default_val;
Packit b099d7
Packit b099d7
    if (XmTree_orientation(tw) == XmVERTICAL)
Packit b099d7
        default_val = 20;
Packit b099d7
    else
Packit b099d7
        default_val = 2;
Packit b099d7
Packit b099d7
    value->addr = (XtPointer) &default_val;
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: LineColorDefault
Packit b099d7
 *	Description: Sets the default line color to the parent's 
Packit b099d7
 *                   foreground color.
Packit b099d7
 *	Arguments: w - the widget to set the line color on.
Packit b099d7
 *                 offset - offset of the field in the widget record.
Packit b099d7
 *                 value - resource descriptor to return.
Packit b099d7
 *	Returns: none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void 
Packit b099d7
LineColorDefault(Widget widget, int offset, XrmValue *value)
Packit b099d7
{
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) XtParent(widget);
Packit b099d7
Packit b099d7
    value->addr = (XtPointer) &(tw->manager.foreground);
Packit b099d7
}
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void 
Packit b099d7
LineBackgroundColorDefault(Widget widget, int offset, XrmValue *value)
Packit b099d7
{
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) XtParent(widget);
Packit b099d7
Packit b099d7
    value->addr = (XtPointer) &(tw->core.background_pixel);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: DrawExtraLadderLines 
Packit b099d7
 *	Description: Draws the extra horizontal and vertical ladder lines 
Packit b099d7
 *                   that connect elements of the tree.
Packit b099d7
 *	Arguments: w - the tree widget.
Packit b099d7
 *                 gc - gc of the parent node
Packit b099d7
 *                 first_kid - start points for vertical line
Packit b099d7
 *                 last_kid - end points for vertical line
Packit b099d7
 *                 parent_point - supplies y end points for horizontal line
Packit b099d7
 *	Returns: none
Packit b099d7
 */
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void
Packit b099d7
DrawExtraLadderLines( Widget w, GC gc, LadderPoint first_kid,
Packit b099d7
		      LadderPoint last_kid, LadderPoint parent_point )
Packit b099d7
{
Packit b099d7
  XmTreeWidget tw = (XmTreeWidget)w;
Packit b099d7
  
Packit b099d7
  if (XmTree_connect_style(tw) == XmTreeLadder)
Packit b099d7
    {
Packit b099d7
      
Packit b099d7
      /* First draw the line that starts at parent midpoint and goes
Packit b099d7
       *    to the ladder line connecting the children. Then draw the
Packit b099d7
       *    line connecting the children.
Packit b099d7
       */
Packit b099d7
Packit b099d7
      if (XmTree_orientation(tw) == XmHORIZONTAL)
Packit b099d7
      {
Packit b099d7
          XDrawLine(XtDisplay(w), XtWindow(w), gc, parent_point.x,
Packit b099d7
		parent_point.y, first_kid.x, parent_point.y ); 
Packit b099d7
          XDrawLine(XtDisplay(w), XtWindow(w), gc, first_kid.x, first_kid.y,
Packit b099d7
		first_kid.x, last_kid.y );
Packit b099d7
      }
Packit b099d7
      else    /* orientation == XmVERTICAL */
Packit b099d7
      {
Packit b099d7
          XDrawLine(XtDisplay(w), XtWindow(w), gc, parent_point.x,
Packit b099d7
		parent_point.y, parent_point.x, first_kid.y ); 
Packit b099d7
          XDrawLine(XtDisplay(w), XtWindow(w), gc, first_kid.x, first_kid.y,
Packit b099d7
		last_kid.x, first_kid.y );
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
  
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*	Function Name: RedrawTreeLines;
Packit b099d7
 *	Description: Redraws the lines that connect elements of the tree.
Packit b099d7
 *	Arguments: w - the tree widget.
Packit b099d7
 *                 rect - the rectangle to clip to.
Packit b099d7
 *	Returns: none
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
RedrawTreeLines(Widget w, XRectangle * rect)
Packit b099d7
{
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) w;
Packit b099d7
Packit b099d7
    if (XtIsRealized(w))
Packit b099d7
	DrawTreeLine(w, rect, (TreeConstraints) XmHierarchy_top_node(tw));
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: _CalcNodeMidPoint
Packit b099d7
 *	Description: Calculates the x and y origin of the
Packit b099d7
 *                   part of the ladder line that comes out of the
Packit b099d7
 *                   parent node
Packit b099d7
 *	Arguments: 
Packit b099d7
 *                 node - The node to calculate points for
Packit b099d7
 *                 w - the tree widget
Packit b099d7
 *                 ret_point - return values for calculated points
Packit b099d7
 *	Returns: none
Packit b099d7
 */
Packit b099d7
static void
Packit b099d7
_CalcNodeMidPoint( TreeConstraints node, Widget w,
Packit b099d7
		   LadderPoint *ret_point )
Packit b099d7
{
Packit b099d7
  register int extra_space;
Packit b099d7
  XmTreeWidget tw = (XmTreeWidget)w;
Packit b099d7
Packit b099d7
  if (!XmHierarchyC_widget(node)) return;
Packit b099d7
Packit b099d7
  if (XmTree_orientation(tw) == XmHORIZONTAL)
Packit b099d7
  {
Packit b099d7
    ret_point->x = (XmTreeC_box_x(node) + XmTreeC_widget_offset(node) +
Packit b099d7
		  (XmHierarchyC_widget(node))->core.width + 
Packit b099d7
		  XmHierarchy_h_margin(tw));
Packit b099d7
  
Packit b099d7
    extra_space = GetExtraVertSpace(w);
Packit b099d7
  
Packit b099d7
    ret_point->y = XmTreeC_box_y(node)+(int)(XmTreeC_bb_height(node)+extra_space)/2;
Packit b099d7
  }
Packit b099d7
  else    /* orientation == XmVERTICAL */
Packit b099d7
  {
Packit b099d7
    ret_point->y = (XmTreeC_box_y(node) + XmTreeC_widget_offset(node) +
Packit b099d7
		  (XmHierarchyC_widget(node))->core.height + 
Packit b099d7
		  XmHierarchy_v_margin(tw));
Packit b099d7
  
Packit b099d7
    extra_space = GetExtraHorizSpace(w);
Packit b099d7
  
Packit b099d7
    ret_point->x = XmTreeC_box_x(node)+(int)(XmTreeC_bb_width(node)+extra_space)/2;
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: DrawTreeLine
Packit b099d7
 *	Description: Draws a line between two elements in the tree.
Packit b099d7
 *	Arguments: w - the tree.
Packit b099d7
 *                 rect - the rectangle to clip to.
Packit b099d7
 *                 node - The node to draw lines on. (it also recurses to all
Packit b099d7
 *                        descendants.
Packit b099d7
 *	Returns: none
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
DrawTreeLine(Widget w, XRectangle *rect, TreeConstraints node)
Packit b099d7
{
Packit b099d7
    TreeConstraints * kids;
Packit b099d7
    register int i, num_kids;
Packit b099d7
    TreeConstraints from_node = node;
Packit b099d7
    LadderPoint from_node_point, kid_point, first_kid_point;
Packit b099d7
    LadderPoint last_kid_point;
Packit b099d7
    Boolean first_time=True;
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget)w;
Packit b099d7
Packit b099d7
    if (XmHierarchyC_widget(node) != NULL && !XtIsManaged(XmHierarchyC_widget(node)))
Packit b099d7
	return;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Hunt up the tree until we find a non-hidden parent to be the from
Packit b099d7
     * node.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    while ((XmHierarchyC_parent(from_node) != NULL) && 
Packit b099d7
	   (XmHierarchyC_state(from_node) == XmHidden))
Packit b099d7
    {
Packit b099d7
	from_node = GetNodeInfo(XmHierarchyC_parent(from_node));
Packit b099d7
    }
Packit b099d7
Packit b099d7
    num_kids = XmHierarchyC_num_children(node);
Packit b099d7
    kids = (TreeConstraints *) XmHierarchyC_children(node);
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * This only executes if the root is hidden.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (XmHierarchyC_state(from_node) == XmHidden) {
Packit b099d7
	for (i = 0; i < num_kids; i++, kids++) 
Packit b099d7
	    DrawTreeLine(w, rect, *kids);	/* recurse to descendants. */
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (XmHierarchyC_state(from_node) == XmClosed)
Packit b099d7
	return;
Packit b099d7
Packit b099d7
    _CalcNodeMidPoint( from_node, w, &from_node_point );
Packit b099d7
Packit b099d7
    for (i = 0; i < num_kids; i++, kids++) {
Packit b099d7
      if (XtIsManaged(XmHierarchyC_widget((*kids)))) {
Packit b099d7
	if (XmHierarchyC_state((*kids)) != XmHidden) {
Packit b099d7
	  _DrawLine(w, rect, from_node, *kids, from_node_point, &kid_point);
Packit b099d7
Packit b099d7
	  /* set up the points to draw ladder lines */
Packit b099d7
Packit b099d7
	  if (XmTree_connect_style(tw) == XmTreeLadder) {
Packit b099d7
	    last_kid_point.x = kid_point.x;
Packit b099d7
	    last_kid_point.y = kid_point.y;
Packit b099d7
	    
Packit b099d7
	    if (first_time ){
Packit b099d7
	      first_kid_point.x = last_kid_point.x;
Packit b099d7
	      first_kid_point.y = last_kid_point.y;
Packit b099d7
	      first_time = False;
Packit b099d7
	    }
Packit b099d7
	  }
Packit b099d7
	}
Packit b099d7
	DrawTreeLine(w, rect, *kids);	/* recurse to descendants. */
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* Draw extra ladder lines if necessary.
Packit b099d7
     * If first time False, then we know we've gone through the line
Packit b099d7
     * drawing loop at least twice
Packit b099d7
     */
Packit b099d7
    if ((num_kids > 1) && (!first_time) && (XmTree_connect_style(tw) == XmTreeLadder)) {
Packit b099d7
      DrawExtraLadderLines( w, XmTreeC_gc(node), first_kid_point,
Packit b099d7
			   last_kid_point, from_node_point );
Packit b099d7
    }
Packit b099d7
  }
Packit b099d7
Packit b099d7
/*	Function Name: _DrawLine
Packit b099d7
 *	Description: Draw a tree line between two nodes in the tree. If
Packit b099d7
 *                 child is an only child in XmTreeLadder, then draw a line
Packit b099d7
 *                 directly to it. 
Packit b099d7
 *	Arguments: w - the tree.
Packit b099d7
 *                 rect - the rectangle to clip to. 
Packit b099d7
 *                 parent - The parent.
Packit b099d7
 *                 child - The child to draw the line to.
Packit b099d7
 *                 from_ladder_point - The midpoint of parent where all
Packit b099d7
 *                      lines start from (whether ladder or direct)
Packit b099d7
 *                 to_ladder_point - RETURNs the midpoint of the kid - where
Packit b099d7
 *                      all lines end at (whether ladder or direct)
Packit b099d7
 *	Returns: none
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
_DrawLine(Widget w, XRectangle *rect, TreeConstraints parent, 
Packit b099d7
	  TreeConstraints child, LadderPoint from_ladder_point,
Packit b099d7
	  LadderPoint *to_ladder_point )
Packit b099d7
	  
Packit b099d7
{
Packit b099d7
    GC gc;
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) w;
Packit b099d7
    register int x2, y2, extra_space;
Packit b099d7
    register int rx2, ry2, cx1, cx2, cy1, cy2;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * (from_ladder_point.x, from_ladder_point.y) are the coordinates
Packit b099d7
     *     of the parent's midpoint
Packit b099d7
     * (x2, y2) are the coordinates of the child midpoint
Packit b099d7
     *
Packit b099d7
     * We will end up drawing either a partial ladder line from 
Packit b099d7
     *     (cx1, cy1) to (cx2, cy2) or a full line from 
Packit b099d7
     *     (from_ladder_point.x, from_ladder_point.y) to (x2, y2)
Packit b099d7
     *
Packit b099d7
     * (rx2, ry2) are the coordinates of the lower right of clip rectangle
Packit b099d7
     */
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Must always do the first node since it is what draws the root
Packit b099d7
     * of the ladder.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (child != (TreeConstraints) XmHierarchyC_children(parent)[0] && 
Packit b099d7
	(!(XmHierarchyC_status(child) & IS_MAPPED) || 
Packit b099d7
	 (XmHierarchyC_status(child) & IS_COMPRESSED)))
Packit b099d7
    {
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    gc = XmTreeC_gc(child);
Packit b099d7
	
Packit b099d7
    if (XmTree_orientation(tw) == XmHORIZONTAL)
Packit b099d7
    {
Packit b099d7
      extra_space = GetExtraVertSpace(w);
Packit b099d7
      x2 = (XmTreeC_box_x(child) + XmHierarchy_h_margin(tw));
Packit b099d7
      y2 = XmTreeC_box_y(child) + (int)(XmTreeC_bb_height(child) + extra_space)/2;
Packit b099d7
    }
Packit b099d7
    else     /* orientation == XmVERTICAL */
Packit b099d7
    {
Packit b099d7
      extra_space = GetExtraHorizSpace(w);
Packit b099d7
      y2 = (XmTreeC_box_y(child) + XmHierarchy_v_margin(tw));
Packit b099d7
      x2 = XmTreeC_box_x(child) + (int)(XmTreeC_bb_width(child) + extra_space)/2;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    cx1 = MIN(from_ladder_point.x, x2);
Packit b099d7
    cx2 = MAX(from_ladder_point.x, x2);
Packit b099d7
Packit b099d7
    cy1 = MIN(from_ladder_point.y, y2);
Packit b099d7
    cy2 = MAX(from_ladder_point.y, y2);
Packit b099d7
Packit b099d7
    /* If XmTreeLadder and more than one child, do funky ladder line calc's */
Packit b099d7
Packit b099d7
    if ((XmTree_connect_style(tw) == XmTreeLadder)&&(XmHierarchyC_num_children(parent) > 1))
Packit b099d7
    {
Packit b099d7
        if (XmTree_orientation(tw) == XmHORIZONTAL)
Packit b099d7
        {
Packit b099d7
	  cx1 += (cx2 - cx1)/2;
Packit b099d7
	  cy1 = cy2 = y2;
Packit b099d7
        }
Packit b099d7
        else     /* orientation == XmVERTICAL */
Packit b099d7
        {
Packit b099d7
          if (XmTreeC_is_compressed(child))
Packit b099d7
	      cy1 += (int)(cy2 - XmTree_vertical_delta(tw) - cy1)/(int)2;
Packit b099d7
          else
Packit b099d7
	      cy1 += (cy2 - cy1)/2;
Packit b099d7
	  cx1 = cx2 = x2;
Packit b099d7
        }
Packit b099d7
    }
Packit b099d7
    else /* XmTree_connect_style== XmTreeDirect or only has one child in XmTreeLadder */
Packit b099d7
    {
Packit b099d7
	/* If there is a small pixel difference, make the line straight
Packit b099d7
	 * or it will look wierd.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	if ((cy2-cy1) == 1)
Packit b099d7
	  y2 = from_ladder_point.y;
Packit b099d7
Packit b099d7
	if ((cx2-cx1) == 1)
Packit b099d7
	  x2 = from_ladder_point.x;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    rx2 = rect->x + rect->width;
Packit b099d7
    ry2 = rect->y + rect->height;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Not very pretty, only checks to see if the rect containing the
Packit b099d7
     * line is partially within the exposed rectangle.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (!((cx1 > rx2) || (cy1 > ry2) || (cx2 < rect->x) || (cy2 < rect->y)))
Packit b099d7
    {
Packit b099d7
	if ((XmTree_connect_style(tw) == XmTreeLadder)
Packit b099d7
	    &&(XmHierarchyC_num_children(parent) > 1))
Packit b099d7
	    XDrawLine(XtDisplay(w), XtWindow(w), gc, cx1, cy1, cx2, cy2);
Packit b099d7
	else
Packit b099d7
	    XDrawLine(XtDisplay(w), XtWindow(w), gc, from_ladder_point.x,
Packit b099d7
		      from_ladder_point.y, x2, y2);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* This is sent back because the ladder lines get connected later */
Packit b099d7
    to_ladder_point->x = cx1;
Packit b099d7
    to_ladder_point->y = cy1;
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: CalcLocations
Packit b099d7
 *	Description:   Calculates the location of each widget in the tree.
Packit b099d7
 *	Arguments:     w - the tree widget.
Packit b099d7
 *                     Boolean - attempt resize?
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
CalcLocations(Widget w, Boolean resize_it)
Packit b099d7
{
Packit b099d7
    Cardinal          current_index;
Packit b099d7
    XmTreeWidget      tw = (XmTreeWidget) w;
Packit b099d7
    TreeConstraints   node;
Packit b099d7
    XmTreeWidgetClass tc = (XmTreeWidgetClass) XtClass(w);
Packit b099d7
    register int      i;
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Reset each node to be hidden;
Packit b099d7
     */
Packit b099d7
    for( i = 0; i < tw->composite.num_children; ++i )
Packit b099d7
    {
Packit b099d7
	node = GetNodeInfo(tw->composite.children[i]);
Packit b099d7
	XmHierarchyC_status(node) |= IS_COMPRESSED;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XmHierarchy_num_nodes(tw) = 0;
Packit b099d7
    (void)GetNodeHeightAndWidth(w, (TreeConstraints) XmHierarchy_top_node(tw),
Packit b099d7
			  &(XmHierarchy_num_nodes(tw)), 0);
Packit b099d7
Packit b099d7
    current_index = 0;
Packit b099d7
    {
Packit b099d7
        XmHierarchyBuildTableProc build_node_table;
Packit b099d7
        _XmProcessLock();
Packit b099d7
        build_node_table = tc->hierarchy_class.build_node_table;
Packit b099d7
        _XmProcessUnlock();
Packit b099d7
        (*build_node_table) (w, XmHierarchy_top_node(tw), &current_index);
Packit b099d7
    }
Packit b099d7
    CalcMaxSize(w);
Packit b099d7
    FindNodeLocations(w);		/* Finds the location for each node. */
Packit b099d7
Packit b099d7
    if (resize_it) 
Packit b099d7
	RequestNewSize(w);
Packit b099d7
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: RequestNewSize
Packit b099d7
 *	Description:   Asks our parent for a new size.
Packit b099d7
 *	Arguments:     w - the data request tree widget.
Packit b099d7
 *	Returns:       True if resize happened.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static Boolean
Packit b099d7
RequestNewSize(Widget w)
Packit b099d7
{
Packit b099d7
    Dimension width, height, rwidth, rheight;
Packit b099d7
    XtGeometryResult ret_val;
Packit b099d7
Packit b099d7
    GetDesiredSize(w, &width, &height, False);
Packit b099d7
    ret_val = XtMakeResizeRequest(w, width, height, &rwidth, &rheight);
Packit b099d7
    
Packit b099d7
    if (ret_val == XtGeometryAlmost) 
Packit b099d7
	ret_val = XtMakeResizeRequest(w, rwidth, rheight, NULL, NULL);
Packit b099d7
Packit b099d7
    return(ret_val == XtGeometryYes);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: GetDesiredSize
Packit b099d7
 *	Description:   Returns the desired size of the tree widget.
Packit b099d7
 *	Arguments:     w - the tree widget.
Packit b099d7
 *                     width - the desired width.
Packit b099d7
 *                     height - the desired height.
Packit b099d7
 *                     recalc - recalculate the new size if row height unset?
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
GetDesiredSize(Widget w, Dimension *width, Dimension *height, Boolean recalc)
Packit b099d7
{
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) w;
Packit b099d7
Packit b099d7
    if (recalc)
Packit b099d7
	CalcLocations(w, False);
Packit b099d7
Packit b099d7
    *width = XmTree_max_width(tw);
Packit b099d7
    *height = XmTree_max_height(tw);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: LayoutChildren
Packit b099d7
 *	Description:   all the fun stuff for positioning the children is here.
Packit b099d7
 *	Arguments:     w - the tree widget.
Packit b099d7
 *                     assign_child - A child to assign values to, rather
Packit b099d7
 *                                    than just moving it.
Packit b099d7
 *	Returns:       none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
LayoutChildren(Widget w, Widget assign_child)
Packit b099d7
{
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) w;
Packit b099d7
    XmTreeWidgetClass tc = (XmTreeWidgetClass) XtClass(w);
Packit b099d7
    register HierarchyConstraints * node_table = XmHierarchy_node_table(tw);
Packit b099d7
    register Cardinal num_nodes = XmHierarchy_num_nodes(tw);
Packit b099d7
    register int i, extra_space;
Packit b099d7
    Boolean register_workproc = True;
Packit b099d7
Packit b099d7
    XmDropSiteStartUpdate(w);
Packit b099d7
Packit b099d7
    /*
Packit b099d7
     * Remove the old list, replace it with the new one.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    if (XmListFirst(XmTree_child_op_list(tw)) != NULL) {
Packit b099d7
	if( XmHierarchy_work_proc_id(tw) != (XtWorkProcId) NULL )
Packit b099d7
	{
Packit b099d7
	    XtRemoveWorkProc(XmHierarchy_work_proc_id(tw));
Packit b099d7
	    XmHierarchy_work_proc_id(tw) = (XtWorkProcId) NULL;
Packit b099d7
	}
Packit b099d7
	_XmListFree(XmTree_child_op_list(tw));
Packit b099d7
	XmTree_child_op_list(tw) = _XmListInit();
Packit b099d7
	register_workproc = False;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    /*
Packit b099d7
     * Unmap all nodes that no longer are visible.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    {
Packit b099d7
        XmHierarchyExtraNodeProc unmap_all_extra_nodes;
Packit b099d7
Packit b099d7
        _XmProcessLock();
Packit b099d7
        unmap_all_extra_nodes = tc->hierarchy_class.unmap_all_extra_nodes;
Packit b099d7
        _XmProcessUnlock();
Packit b099d7
        (*unmap_all_extra_nodes) (w, XmHierarchy_top_node(tw));
Packit b099d7
    }
Packit b099d7
    /*
Packit b099d7
     * Go through all nodes that can possibly be displayed, putting those
Packit b099d7
     * that will be visible on the screen and unmapping all others.
Packit b099d7
     */
Packit b099d7
Packit b099d7
    for (i = 0; i < num_nodes; i++, node_table++) {
Packit b099d7
	TreeConstraints t_node = (TreeConstraints) *node_table;
Packit b099d7
	Widget child = XmHierarchyC_widget(t_node);
Packit b099d7
	Widget open_close = XmHierarchyC_open_close_button(t_node);
Packit b099d7
	register Dimension c_height, c_width;
Packit b099d7
	register Position y_loc, x_loc, oc_y_loc = 0, oc_x_loc = 0;
Packit b099d7
Packit b099d7
	c_width = child->core.width + 2 * child->core.border_width;
Packit b099d7
	c_height = child->core.height + 2 * child->core.border_width;
Packit b099d7
	
Packit b099d7
	if (XmTree_orientation(tw) == XmHORIZONTAL) /* DMS */
Packit b099d7
	{
Packit b099d7
		/*
Packit b099d7
		 * Nodes and open close buttons are centered vertically
Packit b099d7
		 * in the box that contains them.
Packit b099d7
		 */
Packit b099d7
		
Packit b099d7
    		extra_space = GetExtraVertSpace(w);
Packit b099d7
		y_loc = (XmTreeC_box_y(t_node) + 
Packit b099d7
			 (int)(XmTreeC_bb_height(t_node) + extra_space - c_height) / 2);
Packit b099d7
	
Packit b099d7
		if (open_close != NULL) {
Packit b099d7
		    Dimension oc_height = (open_close->core.height +
Packit b099d7
					   2 * open_close->core.border_width);
Packit b099d7
	
Packit b099d7
		    oc_y_loc = y_loc + (int)(c_height - oc_height)/2;
Packit b099d7
		}
Packit b099d7
	
Packit b099d7
		oc_x_loc = XmTreeC_box_x(t_node) + XmHierarchy_h_margin(tw);
Packit b099d7
Packit b099d7
		x_loc = oc_x_loc + XmTreeC_widget_offset(t_node);
Packit b099d7
	
Packit b099d7
	} else /* orientation == XmVERTICAL */
Packit b099d7
	{
Packit b099d7
		/*
Packit b099d7
		 * Nodes and open close buttons are centered horizontally
Packit b099d7
		 * in the box that contains them.
Packit b099d7
		 */
Packit b099d7
		
Packit b099d7
    		extra_space = GetExtraHorizSpace(w);
Packit b099d7
	
Packit b099d7
		x_loc = (XmTreeC_box_x(t_node) + 
Packit b099d7
			(int)(XmTreeC_bb_width(t_node) + extra_space - c_width) / 2);
Packit b099d7
	
Packit b099d7
		if (open_close != NULL) {
Packit b099d7
		    Dimension oc_width = (open_close->core.width +
Packit b099d7
					   2 * open_close->core.border_width);
Packit b099d7
	
Packit b099d7
		    oc_x_loc = x_loc + (int)(c_width - oc_width)/2;
Packit b099d7
		}
Packit b099d7
Packit b099d7
	        oc_y_loc = XmTreeC_box_y(t_node) + XmHierarchy_v_margin(tw);
Packit b099d7
Packit b099d7
		y_loc = oc_y_loc + XmTreeC_widget_offset(t_node);
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if (child == assign_child) {
Packit b099d7
	    child->core.x = x_loc;
Packit b099d7
	    child->core.y = y_loc;
Packit b099d7
	}
Packit b099d7
	MoveNode(tw, t_node, x_loc, y_loc, oc_x_loc, oc_y_loc, True);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (register_workproc) {
Packit b099d7
	XmHierarchy_work_proc_id(tw) = 
Packit b099d7
	    XtAppAddWorkProc(XtWidgetToApplicationContext(w), 
Packit b099d7
			     MoveNodesTimer, (XtPointer) w);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XmDropSiteEndUpdate(w);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: GetExtraVertSpace
Packit b099d7
 *	Description: Returns the amount of unused vertical space in the
Packit b099d7
 *                   tree, given the current geometry information.
Packit b099d7
 *	Arguments: w - the tree widget.
Packit b099d7
 *	Returns: see description.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static int
Packit b099d7
GetExtraVertSpace(Widget w)
Packit b099d7
{
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) w;
Packit b099d7
    register int space, vmargin;
Packit b099d7
    TreeConstraints node = (TreeConstraints) XmHierarchy_top_node(tw);
Packit b099d7
Packit b099d7
    space = w->core.height - XmTreeC_bb_height(node);
Packit b099d7
    vmargin = 2 * XmHierarchy_v_margin(tw);
Packit b099d7
Packit b099d7
    return((space > vmargin) ? space : vmargin);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: GetExtraHorizSpace
Packit b099d7
 *	Description: Returns the amount of unused horizontal space in the
Packit b099d7
 *                   tree, given the current geometry information.
Packit b099d7
 *	Arguments: w - the tree widget.
Packit b099d7
 *	Returns: see description.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static int
Packit b099d7
GetExtraHorizSpace(Widget w)
Packit b099d7
{
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) w;
Packit b099d7
    register int space, hmargin;
Packit b099d7
    TreeConstraints node = (TreeConstraints) XmHierarchy_top_node(tw);
Packit b099d7
Packit b099d7
    space = w->core.width - XmTreeC_bb_width(node);
Packit b099d7
    hmargin = 2 * XmHierarchy_h_margin(tw);
Packit b099d7
Packit b099d7
    return((space > hmargin) ? space : hmargin);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: FindNodeLocations
Packit b099d7
 *	Description: Finds the location each node in the node table 
Packit b099d7
 *                   should be placed at.
Packit b099d7
 *	Arguments:   w - the tree widget.
Packit b099d7
 *	Returns: none.
Packit b099d7
 */
Packit b099d7
    
Packit b099d7
static void
Packit b099d7
FindNodeLocations(Widget w)
Packit b099d7
{
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) w;
Packit b099d7
    TreeConstraints * node;
Packit b099d7
    register int i, num_nodes;
Packit b099d7
    Widget *childP;
Packit b099d7
Packit b099d7
    _ResetPlacedFlag((TreeConstraints) XmHierarchy_top_node(tw));
Packit b099d7
Packit b099d7
    ForAllChildren(tw, childP) 
Packit b099d7
	_ResetPlacedFlag(GetNodeInfo(*childP));
Packit b099d7
	
Packit b099d7
    num_nodes = XmHierarchy_num_nodes(tw);
Packit b099d7
    node = (TreeConstraints *) XmHierarchy_node_table(tw);
Packit b099d7
    for (i = 0; i < num_nodes; i++, node++) 
Packit b099d7
	_PlaceNode(w, *node);
Packit b099d7
}
Packit b099d7
 
Packit b099d7
/*	Function Name: _ResetPlacedFlag
Packit b099d7
 *	Description: Resets the placed flag on all notes.
Packit b099d7
 *	Arguments: node - the node to place.
Packit b099d7
 *	Returns: none.
Packit b099d7
 */
Packit b099d7
   
Packit b099d7
static void
Packit b099d7
_ResetPlacedFlag(TreeConstraints node)
Packit b099d7
{
Packit b099d7
    register TreeConstraints *child;
Packit b099d7
    register int i, num;
Packit b099d7
Packit b099d7
    if (node == NULL)
Packit b099d7
	return;
Packit b099d7
Packit b099d7
    XmTreeC_placed(node) = False;
Packit b099d7
Packit b099d7
    child = (TreeConstraints *) XmHierarchyC_children(node);
Packit b099d7
    for (num = XmHierarchyC_num_children(node), i = 0; i < num; i++, child++) 
Packit b099d7
	_ResetPlacedFlag(*child);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: _PlaceNode
Packit b099d7
 *	Description: Actuall Places a node (this is a recursive call).
Packit b099d7
 *	Arguments: w - the tree widget.
Packit b099d7
 *                 node - the node to place.
Packit b099d7
 *	Returns: none.
Packit b099d7
 */
Packit b099d7
   
Packit b099d7
static void
Packit b099d7
_PlaceNode(Widget w, TreeConstraints node)
Packit b099d7
{
Packit b099d7
  XmTreeWidget tw = (XmTreeWidget) w;
Packit b099d7
  register TreeConstraints *child, prev_child, parent;
Packit b099d7
  register Widget pw = XmHierarchyC_parent(node);
Packit b099d7
  register int i, num, x_loc, y_loc, box_amount, boxy, boxx;
Packit b099d7
  
Packit b099d7
  if ((node == NULL) || XmTreeC_placed(node))	/* Already placed. */
Packit b099d7
    return;
Packit b099d7
  
Packit b099d7
  if (pw == NULL) {
Packit b099d7
    if (node == (TreeConstraints) XmHierarchy_top_node(tw)) {
Packit b099d7
      XmTreeC_placed(node) = TRUE;
Packit b099d7
      XmTreeC_box_x(node) = 0;
Packit b099d7
      XmTreeC_box_y(node) = 0;
Packit b099d7
      return;
Packit b099d7
    }
Packit b099d7
    else
Packit b099d7
      parent = (TreeConstraints) XmHierarchy_top_node(tw);
Packit b099d7
  }
Packit b099d7
  else
Packit b099d7
    parent = GetNodeInfo(pw);
Packit b099d7
  
Packit b099d7
  if (!XmTreeC_placed(parent))
Packit b099d7
    _PlaceNode(w, parent);
Packit b099d7
  
Packit b099d7
  /*
Packit b099d7
   * Place all the children of this node.
Packit b099d7
   */
Packit b099d7
  
Packit b099d7
  num = XmHierarchyC_num_children(parent);
Packit b099d7
  
Packit b099d7
  /* 
Packit b099d7
   * Calculate how much room the children take up in the box 
Packit b099d7
   */
Packit b099d7
Packit b099d7
  child = (TreeConstraints * )XmHierarchyC_children(parent);
Packit b099d7
  prev_child = NULL;
Packit b099d7
  box_amount = 0;
Packit b099d7
Packit b099d7
  if (XmTree_orientation(tw) == XmHORIZONTAL)
Packit b099d7
  {
Packit b099d7
    for (i = 0; i < num; child++, i++ ) {
Packit b099d7
      if ((child != NULL) && (XtIsManaged(XmHierarchyC_widget(*child)))){
Packit b099d7
        box_amount += XmTreeC_bb_height(*child);
Packit b099d7
        if (prev_child != NULL)
Packit b099d7
          box_amount += XmTree_v_node_space(tw);
Packit b099d7
        prev_child = *child;
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
    /* center in parent's bounding box */
Packit b099d7
    boxy = XmTreeC_box_y(parent)+((int)(XmTreeC_bb_height(parent)-box_amount)/2);
Packit b099d7
Packit b099d7
    /* 
Packit b099d7
     * Calculate the positions of all the child bounding boxes 
Packit b099d7
     */
Packit b099d7
Packit b099d7
    child = (TreeConstraints *) XmHierarchyC_children(parent);
Packit b099d7
    prev_child = NULL;
Packit b099d7
  
Packit b099d7
    x_loc = XmTreeC_box_x(parent);
Packit b099d7
  
Packit b099d7
    if (XmHierarchyC_state(parent) != XmHidden)
Packit b099d7
      x_loc += (pw->core.width + XmTreeC_widget_offset(parent) + 
Packit b099d7
	      2 * pw->core.border_width + XmTree_h_node_space(tw));
Packit b099d7
Packit b099d7
  
Packit b099d7
    for (i = 0; i < num; i++, child++) 
Packit b099d7
    {
Packit b099d7
      XmTreeC_placed(*child) = TRUE;
Packit b099d7
      XmTreeC_box_x(*child) = x_loc;
Packit b099d7
Packit b099d7
      /* Only calculate for children that have node widgets that are managed */
Packit b099d7
Packit b099d7
      if ((XmHierarchyC_widget(*child))&&
Packit b099d7
	  (XtIsManaged(XmHierarchyC_widget(*child))))
Packit b099d7
	{
Packit b099d7
	  if (prev_child == NULL)
Packit b099d7
	    XmTreeC_box_y(*child) = boxy;
Packit b099d7
	  else
Packit b099d7
	    XmTreeC_box_y(*child) = (XmTreeC_box_y(prev_child) + 
Packit b099d7
				    XmTreeC_bb_height(prev_child) +
Packit b099d7
				    XmTree_v_node_space(tw));
Packit b099d7
	  prev_child = *child;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
  } else   /* orientation == XmVERTICAL */
Packit b099d7
  {
Packit b099d7
    for (i = 0; i < num; child++, i++ ) {
Packit b099d7
      if ((child != NULL) && (XtIsManaged(XmHierarchyC_widget(*child)))){
Packit b099d7
        box_amount += XmTreeC_bb_width(*child);
Packit b099d7
        if ((XmTreeC_is_compressed(*child))
Packit b099d7
        ||  (prev_child && XmTreeC_is_compressed(prev_child)))
Packit b099d7
          box_amount -= XmTree_horizontal_delta(tw);
Packit b099d7
        if (prev_child != NULL)
Packit b099d7
          box_amount += XmTree_h_node_space(tw);
Packit b099d7
        prev_child = *child;
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
    /* center in parent's bounding box */
Packit b099d7
    boxx = XmTreeC_box_x(parent)+((int)(XmTreeC_bb_width(parent)-box_amount)/2);
Packit b099d7
Packit b099d7
    /* 
Packit b099d7
     * Calculate the positions of all the child bounding boxes 
Packit b099d7
     */
Packit b099d7
Packit b099d7
    child = (TreeConstraints *) XmHierarchyC_children(parent);
Packit b099d7
    prev_child = NULL;
Packit b099d7
  
Packit b099d7
    y_loc = XmTreeC_box_y(parent);
Packit b099d7
  
Packit b099d7
    if (XmHierarchyC_state(parent) != XmHidden)
Packit b099d7
      y_loc += (pw->core.height + XmTreeC_widget_offset(parent) + 
Packit b099d7
	      2 * pw->core.border_width + XmTree_v_node_space(tw));
Packit b099d7
Packit b099d7
  for (i = 0; i < num; i++, child++) 
Packit b099d7
    {
Packit b099d7
      XmTreeC_placed(*child) = TRUE;
Packit b099d7
      XmTreeC_box_y(*child) = y_loc;
Packit b099d7
Packit b099d7
      /* Only calculate for children that have node widgets that are managed */
Packit b099d7
Packit b099d7
      if ((XmHierarchyC_widget(*child))&&
Packit b099d7
	  (XtIsManaged(XmHierarchyC_widget(*child))))
Packit b099d7
	{
Packit b099d7
	  if (prev_child == NULL)
Packit b099d7
	    XmTreeC_box_x(*child) = boxx;
Packit b099d7
	  else
Packit b099d7
	    XmTreeC_box_x(*child) = (XmTreeC_box_x(prev_child) + 
Packit b099d7
				    XmTreeC_bb_width(prev_child) +
Packit b099d7
				    XmTree_h_node_space(tw));
Packit b099d7
Packit b099d7
          /*
Packit b099d7
           * If we are doing tree compression, we may have to move this
Packit b099d7
           * widget down. If the compress_style is CompressAll
Packit b099d7
           * then we should compress every other node no matter what.
Packit b099d7
           * If the compress_style == CompressLeaves then we only compress 
Packit b099d7
           * alternating nodes if they have no children.
Packit b099d7
           */
Packit b099d7
Packit b099d7
          if (XmTreeC_is_compressed(*child))
Packit b099d7
	  {
Packit b099d7
	      XmTreeC_box_y(*child) += XmTree_vertical_delta(tw);
Packit b099d7
	      XmTreeC_box_x(*child) -= XmTree_horizontal_delta(tw);
Packit b099d7
	  }
Packit b099d7
          else if (prev_child && XmTreeC_is_compressed(prev_child))
Packit b099d7
	      XmTreeC_box_x(*child) -= XmTree_horizontal_delta(tw);
Packit b099d7
Packit b099d7
          prev_child = *child;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
  }
Packit b099d7
Packit b099d7
}
Packit b099d7
    
Packit b099d7
/*	Function Name: GetNodeHeightAndWidth
Packit b099d7
 *	Description:   Gets the size of each node.
Packit b099d7
 *	Arguments:     w - the drt widget.
Packit b099d7
 *                     node - the node to get the height and width of.
Packit b099d7
 *                     tree_depth - depth of the tree at this node.
Packit b099d7
 * IN/OUT              num - number of nodes.
Packit b099d7
 *                     sib_index - index of this node with relation 
Packit b099d7
 *                          to siblings. Used for vertical compression.
Packit b099d7
 *	Returns:       none
Packit b099d7
 */
Packit b099d7
Packit b099d7
static Boolean
Packit b099d7
GetNodeHeightAndWidth(Widget w, TreeConstraints node, 
Packit b099d7
        Cardinal * num, Cardinal sib_index)
Packit b099d7
{
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) w;
Packit b099d7
    register int i, num_kids, l_width, l_height;
Packit b099d7
Packit b099d7
    if (node == NULL)
Packit b099d7
	return(False);
Packit b099d7
Packit b099d7
    l_width = l_height = 0;
Packit b099d7
Packit b099d7
    XmTreeC_bb_width(node) = XmTreeC_bb_height(node) = 0;
Packit b099d7
Packit b099d7
    if ((node == NULL) || ((XmHierarchyC_widget(node) != NULL) &&
Packit b099d7
			   !XtIsManaged(XmHierarchyC_widget(node)))) 
Packit b099d7
    {
Packit b099d7
	return(False);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (XmHierarchyC_state(node) != XmHidden) {
Packit b099d7
	Widget child = XmHierarchyC_widget(node);
Packit b099d7
	Dimension bw = 2 * child->core.border_width;
Packit b099d7
Packit b099d7
	XmTreeC_bb_width(node) = child->core.width + bw;
Packit b099d7
	XmTreeC_bb_height(node) = child->core.height + bw;
Packit b099d7
Packit b099d7
	/*
Packit b099d7
	 * Leave space to place the open close button if it exists.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	if (XmHierarchyC_open_close_button(node) != NULL) {
Packit b099d7
	    Dimension width, height, border_width;
Packit b099d7
Packit b099d7
	    width = XmHierarchyC_open_close_button(node)->core.width;
Packit b099d7
	    height = XmHierarchyC_open_close_button(node)->core.height;
Packit b099d7
	    border_width = 2*XmHierarchyC_open_close_button(node)->core.border_width;
Packit b099d7
Packit b099d7
	    width += border_width;
Packit b099d7
	    height += border_width;
Packit b099d7
Packit b099d7
	    if (XmTree_orientation(tw) == XmHORIZONTAL)
Packit b099d7
	    {
Packit b099d7
	        width += XmTreeC_open_close_padding(node);
Packit b099d7
Packit b099d7
	        XmTreeC_bb_width(node) += width;
Packit b099d7
	        XmTreeC_widget_offset(node) = width;
Packit b099d7
	        if (height > XmTreeC_bb_height(node)) 
Packit b099d7
		    XmTreeC_bb_height(node) = height;
Packit b099d7
	    }
Packit b099d7
	    else /* orientation == XmVERTICAL */
Packit b099d7
	    {
Packit b099d7
	        height += XmTreeC_open_close_padding(node);
Packit b099d7
Packit b099d7
	        XmTreeC_bb_height(node) += height;
Packit b099d7
	        XmTreeC_widget_offset(node) = height;
Packit b099d7
	        if (width > XmTreeC_bb_width(node)) 
Packit b099d7
		    XmTreeC_bb_width(node) = width;
Packit b099d7
	    }
Packit b099d7
Packit b099d7
	}
Packit b099d7
	else
Packit b099d7
	    XmTreeC_widget_offset(node) = 0;
Packit b099d7
Packit b099d7
	(*num)++;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (XmTree_orientation(tw) == XmHORIZONTAL)
Packit b099d7
    {
Packit b099d7
      num_kids = XmHierarchyC_num_children(node);
Packit b099d7
      if ((XmHierarchyC_state(node) != XmClosed) && (num_kids > 0)) {
Packit b099d7
	register TreeConstraints * child;
Packit b099d7
	register int num_managed=0;
Packit b099d7
Packit b099d7
 	child = (TreeConstraints *) XmHierarchyC_children(node);
Packit b099d7
	
Packit b099d7
	for(i = 0; i < num_kids; i++, child++) {
Packit b099d7
Packit b099d7
	  /* If node values were calculated for this child,
Packit b099d7
	   * and there is more than one child managed, add node
Packit b099d7
	   * space to bounding box size
Packit b099d7
	   *
Packit b099d7
	   * l_height = MAX(sum of N child bounding box heights +
Packit b099d7
	   *              (N-1)*v_node_space, our height);
Packit b099d7
	   * l_width = MAX(child bounding box widths) + 1*h_node_space +
Packit b099d7
	   *              our width;
Packit b099d7
	   */
Packit b099d7
Packit b099d7
	  if (GetNodeHeightAndWidth(w, *child, num, i)) {
Packit b099d7
	    num_managed++;
Packit b099d7
	    if (num_managed > 1)
Packit b099d7
	      l_height += XmTree_v_node_space(tw);
Packit b099d7
	  }
Packit b099d7
	  
Packit b099d7
	  if ((int)l_width < (int)XmTreeC_bb_width(*child))
Packit b099d7
	    l_width = XmTreeC_bb_width(*child);
Packit b099d7
	  
Packit b099d7
	  l_height += XmTreeC_bb_height(*child);
Packit b099d7
Packit b099d7
	}
Packit b099d7
	if (XmHierarchyC_state(node) != XmHidden)
Packit b099d7
	  l_width += XmTree_h_node_space(tw);
Packit b099d7
      }
Packit b099d7
Packit b099d7
      XmTreeC_bb_width(node) += l_width;
Packit b099d7
    
Packit b099d7
      if ((int)XmTreeC_bb_height(node) < (int)l_height)
Packit b099d7
        XmTreeC_bb_height(node) = l_height;
Packit b099d7
    } 
Packit b099d7
    else /* orientation == XmVERTICAL */
Packit b099d7
    {
Packit b099d7
      num_kids = XmHierarchyC_num_children(node);
Packit b099d7
      if ((XmHierarchyC_state(node) != XmClosed) && (num_kids > 0)) {
Packit b099d7
  	register TreeConstraints * child;
Packit b099d7
  	register TreeConstraints prev_child = NULL;
Packit b099d7
  	register int num_managed=0;
Packit b099d7
Packit b099d7
 	child = (TreeConstraints *) XmHierarchyC_children(node);
Packit b099d7
	
Packit b099d7
	for(i = 0; i < num_kids; i++) {
Packit b099d7
Packit b099d7
	  /* If node values were calculated for this child,
Packit b099d7
	   * and there is more than one child managed, add node
Packit b099d7
	   * space to bounding box size
Packit b099d7
	   */
Packit b099d7
Packit b099d7
	  if (GetNodeHeightAndWidth(w, *child, num, i)) {
Packit b099d7
	    num_managed++;
Packit b099d7
	    if (num_managed > 1)
Packit b099d7
	      l_width += XmTree_h_node_space(tw);
Packit b099d7
	  }
Packit b099d7
	  
Packit b099d7
          /*
Packit b099d7
           * If this child is compressed, add the verticalDelta to
Packit b099d7
           * it's height for purposes of calculating our own height
Packit b099d7
           * and subtract the horizontal delta from its width for
Packit b099d7
           * our own width.
Packit b099d7
           * If this child is not compressed, use just its height but
Packit b099d7
           * we still need to subtract the horizontal delta from our
Packit b099d7
           * width if the previous child is compressed.
Packit b099d7
           */
Packit b099d7
          if (XmTreeC_is_compressed(*child))
Packit b099d7
          {
Packit b099d7
	    if ((int)l_height < (int)XmTreeC_bb_height(*child) 
Packit b099d7
                                + (int)XmTree_vertical_delta(tw))
Packit b099d7
	      l_height = XmTreeC_bb_height(*child) + XmTree_vertical_delta(tw);
Packit b099d7
	    l_width += XmTreeC_bb_width(*child) - XmTree_horizontal_delta(tw);
Packit b099d7
          }
Packit b099d7
          else
Packit b099d7
          {
Packit b099d7
	    if ((int)l_height < (int)XmTreeC_bb_height(*child))
Packit b099d7
	      l_height = XmTreeC_bb_height(*child);
Packit b099d7
Packit b099d7
            if (prev_child && XmTreeC_is_compressed(prev_child))
Packit b099d7
	        l_width += XmTreeC_bb_width(*child) - XmTree_horizontal_delta(tw);
Packit b099d7
            else
Packit b099d7
	        l_width += XmTreeC_bb_width(*child);
Packit b099d7
          }
Packit b099d7
	  
Packit b099d7
          prev_child = *child;
Packit b099d7
          child++;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if (XmHierarchyC_state(node) != XmHidden)
Packit b099d7
	  l_height += XmTree_v_node_space(tw);
Packit b099d7
      }
Packit b099d7
Packit b099d7
      XmTreeC_bb_height(node) += l_height;
Packit b099d7
    
Packit b099d7
      if ((int)XmTreeC_bb_width(node) < (int)l_width)
Packit b099d7
        XmTreeC_bb_width(node) = l_width;
Packit b099d7
Packit b099d7
      if ( (((XmTree_compress_style(tw) == XmTreeCompressAll)
Packit b099d7
	        && ((sib_index % 2) == 1))
Packit b099d7
	        && (XmHierarchyC_parent(node) != NULL))
Packit b099d7
          ||   (((XmTree_compress_style(tw) == XmTreeCompressLeaves)
Packit b099d7
                && (num_kids == 0)
Packit b099d7
		&& (XmHierarchyC_parent(node) != NULL)
Packit b099d7
                &&   ((sib_index % 2) == 1))) )
Packit b099d7
      {
Packit b099d7
            XmTreeC_is_compressed(node) = True;
Packit b099d7
      }
Packit b099d7
      else
Packit b099d7
          XmTreeC_is_compressed(node) = False;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    return( True );
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: GetNodeInfo
Packit b099d7
 *	Description:   Gets the node info associated with this widget.
Packit b099d7
 *	Arguments:     w - the widget.
Packit b099d7
 *	Returns:       the node info about this widget.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static TreeConstraints
Packit b099d7
GetNodeInfo(Widget w)
Packit b099d7
{
Packit b099d7
    return((TreeConstraints) w->core.constraints);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: CalcMaxSize
Packit b099d7
 *	Description:   Calculates the maximum width of the tree.
Packit b099d7
 *	Arguments:     w - the tree.
Packit b099d7
 *	Returns:       The max width the tree would like to be.
Packit b099d7
 *
Packit b099d7
 * NOTE:  This is calculating both the max width and the max_height
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
CalcMaxSize(Widget w)
Packit b099d7
{
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) w;
Packit b099d7
    register TreeConstraints node = (TreeConstraints) XmHierarchy_top_node(tw);
Packit b099d7
Packit b099d7
    XmTree_max_width(tw) = XmTreeC_bb_width(node) + 2 * XmHierarchy_h_margin(tw); 
Packit b099d7
    XmTree_max_height(tw) = XmTreeC_bb_height(node) + 2 * XmHierarchy_v_margin(tw);
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 *  Code for handling the node queue.
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: UnmapAllExtraNodes
Packit b099d7
 *	Description:   Correctly unmaps each node in the hierarchy that is 
Packit b099d7
 *                     currently compresed out.
Packit b099d7
 *	Arguments:     w - the ow.
Packit b099d7
 *                     node - node to work one.
Packit b099d7
 *	Returns:       none
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
UnmapAllExtraNodes(Widget w, HierarchyConstraints node)
Packit b099d7
{
Packit b099d7
    register int i, num;
Packit b099d7
    register HierarchyConstraints * ptr;
Packit b099d7
Packit b099d7
    if ((XmHierarchyC_status(node) & IS_COMPRESSED) && 
Packit b099d7
	(XmHierarchyC_status(node) & IS_MAPPED))
Packit b099d7
    {
Packit b099d7
	UnmapNode((XmTreeWidget) w, (TreeConstraints) node);
Packit b099d7
    }
Packit b099d7
	
Packit b099d7
    ptr = XmHierarchyC_children(node);
Packit b099d7
    for (num = XmHierarchyC_num_children(node), i = 0; i < num; i++, ptr++) 
Packit b099d7
	UnmapAllExtraNodes(w, *ptr);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: MoveNode
Packit b099d7
 *	Description: This function adds a widget to the movment queue
Packit b099d7
 *                   but does not move it until it becomes visible.
Packit b099d7
 *	Arguments: tw - the tree widget.
Packit b099d7
 *                 node - the node to move.
Packit b099d7
 *                 x, y - the X and Y location.
Packit b099d7
 *                 oc_x, oc_y - the X and Y location of the open close button.
Packit b099d7
 *                 map - map this child?
Packit b099d7
 *	Returns: none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
MoveNode(XmTreeWidget tw, TreeConstraints node, Position x, Position y,
Packit b099d7
	   Position oc_x, Position oc_y, Boolean map)
Packit b099d7
{
Packit b099d7
    XmTreeC_new_x(node) = x;
Packit b099d7
    XmTreeC_new_y(node) = y;
Packit b099d7
    XmTreeC_oc_new_x(node) = oc_x;
Packit b099d7
    XmTreeC_oc_new_y(node) = oc_y;
Packit b099d7
    XmTreeC_map(node) = map;
Packit b099d7
    XmTreeC_move(node) = True;
Packit b099d7
    XmTreeC_unmap(node) = False;	
Packit b099d7
Packit b099d7
    _XmListAddBefore(XmTree_child_op_list(tw), NULL, (XtPointer) node);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: UnmapNode
Packit b099d7
 *	Description: This function adds a widget to the movment queue
Packit b099d7
 *                   telling it to be unmapped.
Packit b099d7
 *	Arguments: tw - the tree widget.
Packit b099d7
 *                 node - the node to move.
Packit b099d7
 *	Returns: none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
UnmapNode(XmTreeWidget tw, TreeConstraints node)
Packit b099d7
{
Packit b099d7
    XmTreeC_map(node) = False;
Packit b099d7
    XmTreeC_move(node) = False;
Packit b099d7
    XmTreeC_unmap(node) = True;	
Packit b099d7
Packit b099d7
    _XmListAddBefore(XmTree_child_op_list(tw), NULL, (XtPointer) node);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: ProcessChildQueue
Packit b099d7
 *	Description: Processes the child queue.
Packit b099d7
 *	Arguments: tw - the tree widget.
Packit b099d7
 *                 vis - the visible rect.
Packit b099d7
 *	Returns: none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
ProcessChildQueue(XmTreeWidget tw, XRectangle *vis)
Packit b099d7
{
Packit b099d7
    XmListElem *elem, *next;
Packit b099d7
Packit b099d7
    elem = XmListFirst(XmTree_child_op_list(tw)); 
Packit b099d7
    while(elem != NULL) {
Packit b099d7
	TreeConstraints info = (TreeConstraints) XmListElemData(elem);
Packit b099d7
Packit b099d7
	next = XmListElemNext(elem);
Packit b099d7
Packit b099d7
	if (CheckWidget(vis, info))
Packit b099d7
	    _XmListRemove(XmTree_child_op_list(tw), elem);
Packit b099d7
Packit b099d7
	elem = next;
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: CheckWidget
Packit b099d7
 *	Description: This function checks a widget to see if it
Packit b099d7
 *                   needs to be operated on.
Packit b099d7
 *	Arguments:  visible - visible rect.
Packit b099d7
 *                  info - the child op info.
Packit b099d7
 *	Returns: True if operation complete.
Packit b099d7
 * 
Packit b099d7
 * NOTES: A widget will need to be operated on if it is mapped an will show 
Packit b099d7
 *        on the screen, or if the new location is on the screen
Packit b099d7
 *        OR if the node's parent is on the screen
Packit b099d7
 */
Packit b099d7
Packit b099d7
static Boolean
Packit b099d7
CheckWidget(XRectangle * visible, TreeConstraints node)
Packit b099d7
{
Packit b099d7
    if (( ((XmHierarchyC_status(node) & IS_MAPPED) || XmTreeC_map(node)) &&
Packit b099d7
	 (WidgetInRect(visible, XmHierarchyC_open_close_button(node))    ||
Packit b099d7
	  WidgetInRect(visible, XmHierarchyC_widget(node))               ||
Packit b099d7
	  WidgetInRect(visible, XmHierarchyC_parent(node))))             ||
Packit b099d7
	LocInRect(visible, XmHierarchyC_open_close_button(node),
Packit b099d7
		  XmTreeC_oc_new_x(node), XmTreeC_oc_new_y(node))        ||
Packit b099d7
	LocInRect(visible, XmHierarchyC_widget(node),
Packit b099d7
		    XmTreeC_new_x(node), XmTreeC_new_y(node)))
Packit b099d7
    {
Packit b099d7
	ProcessNode(node);
Packit b099d7
	return(True);
Packit b099d7
    }
Packit b099d7
    return(False);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: ProcessNode
Packit b099d7
 *	Description: Processes the request made of this tree node.
Packit b099d7
 *	Arguments: node - the Tree node to process.
Packit b099d7
 *	Returns: none.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static void
Packit b099d7
ProcessNode(TreeConstraints node)
Packit b099d7
{
Packit b099d7
    XmTreeWidgetClass tc;
Packit b099d7
    Widget w = XmHierarchyC_widget(node);
Packit b099d7
Packit b099d7
    if (w == NULL)
Packit b099d7
	return;
Packit b099d7
Packit b099d7
    tc = (XmTreeWidgetClass) XtClass(XtParent(w));
Packit b099d7
    
Packit b099d7
    if (XmTreeC_move(node)) {
Packit b099d7
	_XmMoveWidget(XmHierarchyC_widget(node), 
Packit b099d7
		      XmTreeC_new_x(node), XmTreeC_new_y(node));
Packit b099d7
	
Packit b099d7
	if (XmHierarchyC_open_close_button(node) != NULL) 
Packit b099d7
	    _XmMoveWidget(XmHierarchyC_open_close_button(node),
Packit b099d7
			  XmTreeC_oc_new_x(node), XmTreeC_oc_new_y(node));
Packit b099d7
	XmTreeC_move(node) = False;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (XmTreeC_map(node)) {
Packit b099d7
        XmHierarchyNodeProc map_node;
Packit b099d7
Packit b099d7
        _XmProcessLock();
Packit b099d7
        map_node = tc->hierarchy_class.map_node;
Packit b099d7
        _XmProcessUnlock();
Packit b099d7
Packit b099d7
	    (*map_node)((HierarchyConstraints) node); 
Packit b099d7
    	XmTreeC_map(node) = False;
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (XmTreeC_unmap(node)) {
Packit b099d7
    XmHierarchyNodeProc unmap_node;
Packit b099d7
Packit b099d7
    _XmProcessLock();
Packit b099d7
    unmap_node = tc->hierarchy_class.unmap_node;
Packit b099d7
    _XmProcessUnlock();
Packit b099d7
Packit b099d7
	(*unmap_node)((HierarchyConstraints) node); 
Packit b099d7
	XmTreeC_unmap(node) = False;
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: WidgetInRect
Packit b099d7
 *	Description: Checks to see if widget is in the rect specified.
Packit b099d7
 *	Arguments: rect - the rect to check.
Packit b099d7
 *                 w - the widget to check.
Packit b099d7
 *	Returns: True if the widget is in the regien specified.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static Boolean
Packit b099d7
WidgetInRect(XRectangle *rect, Widget w)
Packit b099d7
{
Packit b099d7
    if (w == NULL)
Packit b099d7
	return(False);
Packit b099d7
Packit b099d7
    return(LocInRect(rect, w, w->core.x, w->core.y));
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: LocInRect
Packit b099d7
 *	Description: Checks to see if widget is in the rect specified.
Packit b099d7
 *                   given new X and Y locations.
Packit b099d7
 *	Arguments: rect - the rectangle to check.
Packit b099d7
 *                 w - the widget to check.
Packit b099d7
 *                 x, y - the new x and y locations.
Packit b099d7
 *	Returns: True if the widget is in the regien specified.
Packit b099d7
 */
Packit b099d7
Packit b099d7
static Boolean
Packit b099d7
LocInRect(XRectangle *rect, Widget w, Position x, Position y)
Packit b099d7
{ 
Packit b099d7
    register int x1, x2;
Packit b099d7
    register int y1, y2;
Packit b099d7
Packit b099d7
    if (w == NULL)
Packit b099d7
	return(False);
Packit b099d7
Packit b099d7
    x1 = x + w->core.width;
Packit b099d7
    y1 = y + w->core.height;
Packit b099d7
Packit b099d7
    x2 = rect->x + rect->width;
Packit b099d7
    y2 = rect->y + rect->height;
Packit b099d7
Packit b099d7
    return (!((x > x2) || (y > y2) || (x1 < rect->x) || (y1 < rect->y)));
Packit b099d7
}
Packit b099d7
Packit b099d7
/*	Function Name: MoveNodesTimer
Packit b099d7
 *	Description: processes one node from the movemont queue.
Packit b099d7
 *	Arguments: data - A Pointer to the tree widget.
Packit b099d7
 *                 id - th ext interval id.
Packit b099d7
 *	Returns: none
Packit b099d7
 */
Packit b099d7
Packit b099d7
/* ARGSUSED */
Packit b099d7
static Boolean
Packit b099d7
MoveNodesTimer(XtPointer data)
Packit b099d7
{
Packit b099d7
    XmTreeWidget tw = (XmTreeWidget) data;
Packit b099d7
    XmListElem *elem = XmListFirst(XmTree_child_op_list(tw));
Packit b099d7
Packit b099d7
    if (elem != NULL) { 
Packit b099d7
	TreeConstraints node = (TreeConstraints) XmListElemData(elem);
Packit b099d7
	ProcessNode(node);
Packit b099d7
	_XmListRemove(XmTree_child_op_list(tw), elem);
Packit b099d7
	return( False );
Packit b099d7
    }
Packit b099d7
Packit b099d7
    XmHierarchy_work_proc_id(tw) = (XtWorkProcId) NULL;
Packit b099d7
    return( True );
Packit b099d7
}
Packit b099d7
Packit b099d7
static void LineStyle_confirm (Widget w, int value)
Packit b099d7
{
Packit b099d7
	TreeConstraints node = GetNodeInfo(w);
Packit b099d7
	switch (XmTreeC_line_style(node))
Packit b099d7
	{
Packit b099d7
	case LineSolid:
Packit b099d7
	case LineOnOffDash:
Packit b099d7
	case LineDoubleDash:
Packit b099d7
		break;
Packit b099d7
	default:
Packit b099d7
		/* error */
Packit b099d7
		XmTreeC_line_style(node) = value;
Packit b099d7
		break;
Packit b099d7
	}
Packit b099d7
}
Packit b099d7
Packit b099d7
/************************************************************
Packit b099d7
 *
Packit b099d7
 *  Public functions.
Packit b099d7
 *
Packit b099d7
 ************************************************************/
Packit b099d7
Packit b099d7
/*	Function Name: XmCreateTree
Packit b099d7
 *	Description: Creation Routine for UIL and ADA.
Packit b099d7
 *	Arguments: parent - the parent widget.
Packit b099d7
 *                 name - the name of the widget.
Packit b099d7
 *                 args, num_args - the number and list of args.
Packit b099d7
 *	Returns: The created widget.
Packit b099d7
 */
Packit b099d7
Packit b099d7
Widget
Packit b099d7
XmCreateTree(Widget parent, String name,
Packit b099d7
	     ArgList args, Cardinal num_args)
Packit b099d7
{
Packit b099d7
    return(XtCreateWidget(name, xmTreeWidgetClass, parent, args, num_args));
Packit b099d7
}