home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume8 / dtree / part02 < prev    next >
Text File  |  1990-08-15  |  28KB  |  863 lines

  1. Path: uunet!decwrl!apple!sun-barr!newstop!sun!hpkronos.hpl.hp.com
  2. From: kk@hpkronos.hpl.hp.com (Konstantinos Konstantinides)
  3. Newsgroups: comp.sources.x
  4. Subject: v08i073: dtree, Part02/02
  5. Message-ID: <140747@sun.Eng.Sun.COM>
  6. Date: 16 Aug 90 03:04:43 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 852
  9. Approved: argv@sun.com
  10.  
  11. Submitted-by: Konstantinos Konstantinides <kk@hpkronos.hpl.hp.com>
  12. Posting-number: Volume 8, Issue 73
  13. Archive-name: dtree/part02
  14.  
  15. # This is a shell archive.  Remove anything before this line,
  16. # then unpack it by saving it in a file and typing "sh file".
  17. #
  18. # Wrapped by Konstantinos Konstantinides <kk@hpkronos> on Tue Aug 14 15:06:51 1990
  19. #
  20. # This archive contains:
  21. #    Tree.c    Tree.h    TreeP.h    
  22. #
  23.  
  24. LANG=""; export LANG
  25. PATH=/bin:/usr/bin:$PATH; export PATH
  26.  
  27. echo x - Tree.c
  28. cat >Tree.c <<'@EOF'
  29. /**********************************************************************************
  30.   * Tree.c: The Tree Widget Source File
  31.   *         From:
  32.   *                   The X Window System, 
  33.   *            Programming and Applications with Xt
  34.   *                   OSF/Motif Edition
  35.   *         by
  36.   *                Douglas Young
  37.   *              Prentice Hall, 1990
  38.   *
  39.   *                 Example described on pages: 397-419
  40.   *
  41.   *
  42.   *  Copyright 1989 by Prentice Hall
  43.   *  All Rights Reserved
  44.   *
  45.   * This code is based on the OSF/Motif widget set and the X Window System
  46.   *
  47.   * Permission to use, copy, modify, and distribute this software for 
  48.   * any purpose and without fee is hereby granted, provided that the above
  49.   * copyright notice appear in all copies and that both the copyright notice
  50.   * and this permission notice appear in supporting documentation.
  51.   *
  52.   * Prentice Hall and the author disclaim all warranties with regard to 
  53.   * this software, including all implied warranties of merchantability and fitness.
  54.   * In no event shall Prentice Hall or the author be liable for any special,
  55.   * indirect or cosequential damages or any damages whatsoever resulting from 
  56.   * loss of use, data or profits, whether in an action of contract, negligence 
  57.   * or other tortious action, arising out of or in connection with the use 
  58.   * or performance of this software.
  59.   *
  60.   * Open Software Foundation is a trademark of The Open Software Foundation, Inc.
  61.   * OSF is a trademark of Open Software Foundation, Inc.
  62.   * OSF/Motif is a trademark of Open Software Foundation, Inc.
  63.   * Motif is a trademark of Open Software Foundation, Inc.
  64.   * DEC is a registered trademark of Digital Equipment Corporation
  65.   * HP is a registered trademark of the Hewlett Packard Company
  66.   * DIGITAL is a registered trademark of Digital Equipment Corporation
  67.   * X Window System is a trademark of the Massachusetts Institute of Technology
  68.   **********************************************************************************/
  69.  
  70.  
  71. #include      <X11/Intrinsic.h>
  72. #include      <X11/IntrinsicP.h>
  73. #include      <X11/StringDefs.h>
  74. #include      <X11/CoreP.h>
  75. #include      <X11/CompositeP.h>
  76. #include      <X11/ConstrainP.h>
  77. #include      "Tree.h"
  78. #include      "TreeP.h"
  79. #define   MAX(a,b) ((a) > (b) ? (a) : (b))
  80.  
  81. static void             Initialize();
  82. static void             ConstraintInitialize();
  83. static void             ConstraintDestroy();
  84. static Boolean          ConstraintSetValues();
  85. static Boolean          SetValues();
  86. static XtGeometryResult GeometryManager();
  87. static void             ChangeManaged();
  88. static void             insert_new_node();
  89. static void             delete_node();
  90. static void             new_layout();
  91. static void             Redisplay();
  92. static TreeOffsetPtr    create_offset();
  93. static int              compute_positions();
  94. static void             shift_subtree();
  95. static void             set_positions();
  96. static void             reset();
  97. static Position         current_position();
  98. static void             set_current_position();
  99. static Position         sum_of_positions();
  100.  
  101. static XtResource resources[] = {
  102.  {XtNhorizontalSpace,XtCSpace,XtRDimension,sizeof(Dimension),
  103.    XtOffset(XsTreeWidget, tree.h_min_space), XtRString,"15" },
  104.  {XtNverticalSpace,XtCSpace, XtRDimension,sizeof (Dimension),
  105.    XtOffset(XsTreeWidget, tree.v_min_space), XtRString,"5"  },
  106.  {XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
  107.   XtOffset(XsTreeWidget, tree.foreground), XtRString,"Black"},
  108. };
  109.  
  110. static XtResource treeConstraintResources[] = {
  111.  {XtNsuperNode, XtCSuperNode, XtRPointer, sizeof(Widget),
  112.    XtOffset(TreeConstraints, tree.super_node),
  113.    XtRPointer, NULL},
  114. };
  115.  
  116. XsTreeClassRec XstreeClassRec = {
  117.   {
  118.     /* core_class fields  */
  119.     (WidgetClass) &constraintClassRec,/* superclass         */
  120.     "Tree",                           /* class_name         */
  121.     sizeof(XsTreeRec),                /* widget_size        */
  122.     NULL,                             /* class_init         */
  123.     NULL,                             /* class_part_init    */
  124.     FALSE,                            /* class_inited       */    
  125.     Initialize,                       /* initialize         */
  126.     NULL,                             /* initialize_hook    */    
  127.     XtInheritRealize,                 /* realize            */
  128.     NULL,                             /* actions            */
  129.     0,                                /* num_actions        */    
  130.     resources,                        /* resources          */
  131.     XtNumber(resources),              /* num_resources      */
  132.     NULLQUARK,                        /* xrm_class          */
  133.     TRUE,                             /* compress_motion    */    
  134.     TRUE,                             /* compress_exposure  */    
  135.     TRUE,                             /* compress_enterleave*/    
  136.     TRUE,                             /* visible_interest   */
  137.     NULL,                             /* destroy            */
  138.     NULL,                             /* resize             */
  139.     Redisplay,                        /* expose             */
  140.     SetValues,                        /* set_values         */
  141.     NULL,                             /* set_values_hook    */    
  142.     XtInheritSetValuesAlmost,         /* set_values_almost  */
  143.     NULL,                             /* get_values_hook    */    
  144.     NULL,                             /* accept_focus       */
  145.     XtVersion,                        /* version            */    
  146.     NULL,                             /* callback_private   */
  147.     NULL,                             /* tm_table           */
  148.     NULL,                             /* query_geometry     */    
  149.     NULL,                             /* display_accelerator*/
  150.     NULL,                             /* extension          */
  151.   },
  152.   {
  153.     /* composite_class fields */
  154.     GeometryManager,                 /* geometry_manager    */
  155.     ChangeManaged,                   /* change_managed      */
  156.     XtInheritInsertChild,            /* insert_child        */    
  157.     XtInheritDeleteChild,            /* delete_child        */    
  158.     NULL,                            /* extension           */
  159.   },
  160.   { 
  161.     /* constraint_class fields */
  162.    treeConstraintResources,          /* subresources        */
  163.    XtNumber(treeConstraintResources),/* subresource_count   */
  164.    sizeof(TreeConstraintsRec),       /* constraint_size     */
  165.    ConstraintInitialize,             /* initialize          */
  166.    ConstraintDestroy,                /* destroy             */
  167.    ConstraintSetValues,              /* set_values          */
  168.    NULL,                             /* extension           */
  169.    },
  170.   {
  171.     /* Tree class fields */
  172.     0,                               /* ignore              */    
  173.   }
  174. };
  175.  
  176. WidgetClass XstreeWidgetClass = (WidgetClass) &XstreeClassRec;
  177.  
  178. static void Initialize(request, new)
  179.     XsTreeWidget request, new;
  180. {
  181.   Arg       wargs[2];
  182.   XGCValues values;
  183.   XtGCMask  valueMask;
  184.   /*
  185.    * Make sure the widget's width and height are 
  186.    * greater than zero.
  187.    */
  188.   if (request->core.width <= 0)
  189.     new->core.width = 5;
  190.   if (request->core.height <= 0)
  191.     new->core.height = 5;
  192.   /*
  193.    * Create a graphics context for the connecting lines.
  194.    */
  195.   valueMask = GCForeground | GCBackground;
  196.   values.foreground = new->tree.foreground;
  197.   values.background = new->core.background_pixel;
  198.   new->tree.gc = XtGetGC (new, valueMask, &values);  
  199.   /*
  200.    * Create the hidden root widget.
  201.    */
  202.   new->tree.tree_root = (Widget) NULL;
  203.   XtSetArg(wargs[0], XtNwidth, 1);
  204.   XtSetArg(wargs[1], XtNheight, 1);
  205.   new->tree.tree_root = 
  206.           XtCreateWidget("root", widgetClass, new, wargs, 2);
  207.   /*
  208.    * Allocate the tables used by the layout
  209.    * algorithm.
  210.    */
  211.   new->tree.horizontal = create_offset(10);
  212.   new->tree.vertical   = create_offset(10);
  213.  
  214. static void ConstraintInitialize(request, new)
  215.      Widget request, new;
  216. {
  217.   TreeConstraints tree_const = TREE_CONSTRAINT(new);
  218.   XsTreeWidget tw = (XsTreeWidget) new->core.parent;
  219.   /*
  220.    * Initialize the widget to have no sub-nodes.
  221.    */
  222.   tree_const->tree.n_sub_nodes = 0;
  223.   tree_const->tree.max_sub_nodes = 0;
  224.   tree_const->tree.sub_nodes = (WidgetList) NULL;
  225.   tree_const->tree.x = tree_const->tree.y = 0; 
  226.   /*
  227.    * If this widget has a super-node, add it to that 
  228.    * widget' sub-nodes list. Otherwise make it a sub-node of 
  229.    * the tree_root widget.
  230.    */
  231.   if(tree_const->tree.super_node)
  232.     insert_new_node(tree_const->tree.super_node, new);
  233.   else
  234.     if(tw->tree.tree_root)
  235.       insert_new_node(tw->tree.tree_root, new);
  236.  
  237. static Boolean SetValues(current, request, new)
  238.     XsTreeWidget current, request, new;
  239. {
  240.  int       redraw = FALSE;
  241.  XGCValues values;
  242.  XtGCMask  valueMask;
  243.  /*
  244.   * If the foreground color has changed, redo the GC's
  245.   * and indicate a redraw.
  246.   */
  247.  if (new->tree.foreground != current->tree.foreground ||
  248.      new->core.background_pixel !=
  249.                            current->core.background_pixel){
  250.    valueMask         = GCForeground | GCBackground;
  251.    values.foreground = new->tree.foreground;
  252.    values.background = new->core.background_pixel;
  253.    XtReleaseGC(new, new->tree.gc);
  254.    new->tree.gc    = XtGetGC (new, valueMask, &values);   
  255.    redraw = TRUE;     
  256.  }
  257.  /*
  258.   * If the minimum spacing has changed, recalculate the
  259.   * tree layout. new_layout() does a redraw, so we don't
  260.   * need SetValues to do another one.
  261.   */
  262.  if (new->tree.v_min_space != current->tree.v_min_space ||
  263.      new->tree.h_min_space != current->tree.h_min_space){ 
  264.    new_layout(new);
  265.    redraw = FALSE;
  266.  }
  267.  return (redraw);
  268. }
  269.  
  270. static Boolean ConstraintSetValues(current, request, new)
  271.     Widget current, request, new;
  272. {
  273.  TreeConstraints newconst = TREE_CONSTRAINT(new);
  274.  TreeConstraints current_const = TREE_CONSTRAINT(current);
  275.  XsTreeWidget tw = (XsTreeWidget) new->core.parent;
  276.  /*
  277.   * If the super_node field has changed, remove the widget
  278.   * from the old widget's sub_nodes list and add it to the
  279.   * new one.
  280.   */
  281.  if(current_const->tree.super_node !=
  282.                                   newconst->tree.super_node){
  283.    if(current_const->tree.super_node)
  284.      delete_node(current_const->tree.super_node, new);
  285.    if(newconst->tree.super_node)
  286.      insert_new_node(newconst->tree.super_node, new);
  287.    /*
  288.     * If the Tree widget has been realized, 
  289.     * compute new layout.
  290.     */
  291.    if(XtIsRealized(tw))
  292.      new_layout(tw);
  293.   }               
  294.   return (False);
  295. }
  296.  
  297. static void insert_new_node(super_node, node)
  298.      Widget super_node, node;
  299. {
  300.   TreeConstraints super_const = TREE_CONSTRAINT(super_node);
  301.   TreeConstraints node_const = TREE_CONSTRAINT(node);
  302.   int index = super_const->tree.n_sub_nodes;
  303.   
  304.   node_const->tree.super_node = super_node;
  305.   /*
  306.    * If there is no more room in the sub_nodes array, 
  307.    * allocate additional space.
  308.    */  
  309.   if(super_const->tree.n_sub_nodes ==
  310.                              super_const->tree.max_sub_nodes){
  311.     super_const->tree.max_sub_nodes += 
  312.                     (super_const->tree.max_sub_nodes / 2) + 2;
  313.     super_const->tree.sub_nodes = 
  314.      (WidgetList) XtRealloc(super_const->tree.sub_nodes, 
  315.                            (super_const->tree.max_sub_nodes) *
  316.                             sizeof(Widget));
  317.   } 
  318.   /*
  319.    * Add the sub_node in the next available slot and 
  320.    * increment the counter.
  321.    */
  322.   super_const->tree.sub_nodes[index] = node;
  323.   super_const->tree.n_sub_nodes++;
  324. }
  325.  
  326. static void delete_node(super_node, node)
  327.     Widget  super_node, node;
  328. {
  329.   TreeConstraints node_const = TREE_CONSTRAINT(node);
  330.   TreeConstraints super_const;
  331.   int             pos, i;
  332.   /*
  333.    * Make sure the super_node exists.
  334.    */
  335.   if(!super_node) return;  
  336.   
  337.   super_const = TREE_CONSTRAINT(super_node);
  338.   /*
  339.    * Find the sub_node on its super_node's list.
  340.    */
  341.   for (pos = 0; pos < super_const->tree.n_sub_nodes; pos++)
  342.     if (super_const->tree.sub_nodes[pos] == node)
  343.       break;
  344.   if (pos == super_const->tree.n_sub_nodes) return;
  345.   /*
  346.    * Decrement the number of sub_nodes
  347.    */  
  348.   super_const->tree.n_sub_nodes--;
  349.   /*
  350.    * Fill in the gap left by the sub_node.
  351.    * Zero the last slot for good luck.
  352.    */
  353.   for (i = pos; i < super_const->tree.n_sub_nodes; i++) 
  354.     super_const->tree.sub_nodes[i] = 
  355.                             super_const->tree.sub_nodes[i+1];
  356.  super_const->tree.sub_nodes[super_const->tree.n_sub_nodes]=0;
  357. }
  358.  
  359. static void ConstraintDestroy(w) 
  360. #ifdef JUST_LIKE_BOOK  /* Unimportant but perhaps confusing */
  361.      XsTreeWidget w;
  362. #else
  363.      Widget w;
  364. #endif
  365.   TreeConstraints tree_const = TREE_CONSTRAINT(w);
  366.   int i;
  367.  /* 
  368.   * Remove the widget from its parent's sub-nodes list and
  369.   * make all this widget's sub-nodes sub-nodes of the parent.
  370.   */
  371.   if(tree_const->tree.super_node) { 
  372.     delete_node(tree_const->tree.super_node, w);
  373.     for(i=0;i< tree_const->tree.n_sub_nodes; i++)
  374.       insert_new_node(tree_const->tree.super_node, 
  375.                       tree_const->tree.sub_nodes[i]);
  376.   }
  377.   new_layout(w->core.parent);
  378. }
  379.  
  380. static XtGeometryResult GeometryManager(w, request, reply)
  381.     Widget               w;
  382.     XtWidgetGeometry    *request;
  383.     XtWidgetGeometry    *reply;
  384. {
  385.  
  386.  XsTreeWidget tw = (XsTreeWidget) w->core.parent;
  387.  /*
  388.   * No position changes allowed!.
  389.   */
  390.  if ((request->request_mode & CWX && request->x!=w->core.x)
  391.      ||(request->request_mode & CWY && request->y!=w->core.y))
  392.   return (XtGeometryNo);
  393.  /*
  394.   * Allow all resize requests.
  395.   */
  396.  if (request->request_mode & CWWidth)
  397.    w->core.width = request->width;
  398.  if (request->request_mode & CWHeight)
  399.    w->core.height = request->height;
  400.  if (request->request_mode & CWBorderWidth)
  401.    w->core.border_width = request->border_width;
  402.  /*
  403.   *  Compute the new layout based on the new widget sizes;
  404.   */
  405.  new_layout(tw);
  406.  return (XtGeometryYes);
  407. }
  408.  
  409. static void ChangeManaged(tw)
  410.     XsTreeWidget tw;
  411. {
  412.   new_layout(tw);
  413. }
  414.  
  415.  
  416. static void Redisplay (w, event, region)
  417.      XsTreeWidget   w;
  418.      XEvent        *event;
  419.      Region         region;
  420. {
  421.   int              i, j;
  422.   TreeConstraints tree_const;
  423.   Widget          child;
  424.   /*
  425.    * If the Tree widget is visible, visit each managed child.
  426.    */
  427.   if(w->core.visible)
  428.    for (i = 0; i < w -> composite.num_children; i++){
  429.      child = w -> composite.children[i];
  430.      tree_const = TREE_CONSTRAINT(child);
  431.      /*
  432.       * Draw a line between the right edge of each widget
  433.       * and the left edge of each of its sub_nodes. Don't
  434.       * draw lines from the fake tree_root.
  435.       */
  436.      if(child != w->tree.tree_root && 
  437.         tree_const->tree.n_sub_nodes)
  438.        for (j = 0; j < tree_const->tree.n_sub_nodes; j++)
  439.          XDrawLine(XtDisplay(w), XtWindow(w), 
  440.                    w->tree.gc,
  441.                    child->core.x + child->core.width, 
  442.                    child->core.y + child->core.height / 2,
  443.                    tree_const->tree.sub_nodes[j]->core.x,
  444.                    tree_const->tree.sub_nodes[j]->core.y + 
  445.                 tree_const->tree.sub_nodes[j]->core.height/2);
  446.     }
  447. }
  448.  
  449. static void new_layout(tw)
  450.      XsTreeWidget   tw;
  451. {
  452.   /*
  453.    *  Reset the auxiliary tables.
  454.    */
  455.   reset(tw->tree.vertical);
  456.   reset(tw->tree.horizontal);
  457.   /*
  458.    * Compute each widget's x,y position
  459.    */
  460.   compute_positions(tw, tw->tree.tree_root, 0);
  461.   /*
  462.    * Move each widget into place.
  463.    */
  464.   set_positions(tw, tw->tree.tree_root, 0, 0);
  465.   /*
  466.    * Trigger a redisplay of the lines connecting nodes.
  467.    */
  468.   if(XtIsRealized(tw))
  469.     XClearArea(XtDisplay(tw), XtWindow(tw), 0, 0, 0, 0, TRUE);
  470. }
  471.  
  472.  static int compute_positions(tw, w, level)
  473.      XsTreeWidget tw;
  474.      Widget       w;
  475.      long         level;
  476. {
  477.  Position       current_hpos, current_vpos;
  478.  int             i, depth = 0;
  479.  TreeConstraints tree_const = TREE_CONSTRAINT(w);
  480.  /*
  481.   * Get the current positions for this level.
  482.   */
  483.  current_hpos = current_position(tw->tree.horizontal, level);
  484.  current_vpos = current_position(tw->tree.vertical, level);
  485.  /*
  486.   * Set the current horizontal width to the max widths of all
  487.   * widgets at this level.
  488.   */
  489.  set_current_position(tw->tree.horizontal, level, 
  490.                       MAX(current_hpos, w->core.width));
  491.  /*
  492.   * If the node has no sub_nodes, just set the vertical 
  493.   * position to the next available space.
  494.   */
  495.  if(tree_const->tree.n_sub_nodes == 0){
  496.    tree_const->tree.y = current_vpos;
  497.  }
  498.  else {
  499.    Widget          first_kid, last_kid;
  500.    TreeConstraints const1, const2;
  501.    Position        top, bottom;
  502.   /*
  503.    * If the node has sub_nodes, recursively figure the 
  504.    * positions of each sub_node.
  505.    */
  506.    for(i = 0; i < tree_const->tree.n_sub_nodes; i++)
  507.     depth = compute_positions(tw, 
  508.                               tree_const->tree.sub_nodes[i],
  509.                               level + 1);
  510.   /*
  511.    * Now that the vertical positions of all children are 
  512.    * known, find the vertical extent of all sub_nodes.
  513.    */
  514.   first_kid= tree_const->tree.sub_nodes[0];
  515.   last_kid = 
  516.    tree_const->tree.sub_nodes[tree_const->tree.n_sub_nodes-1];
  517.   const1   = TREE_CONSTRAINT(first_kid);
  518.   const2   = TREE_CONSTRAINT(last_kid);
  519.   top      = const1->tree.y + first_kid->core.height / 2; 
  520.   bottom   = const2->tree.y + last_kid->core.height / 2;
  521.   /*
  522.    * Set the node's position to the center of its sub_nodes.
  523.    */
  524.   tree_const->tree.y = (top + bottom)/2 - (w->core.height/ 2);
  525.   /*
  526.    * If this position is less than the next available 
  527.    * position, correct it to be the next available
  528.    * position, calculate the amount by which all sub_nodes
  529.    * must be shifted, and shift the entire sub-tree.
  530.    */
  531.    if(tree_const->tree.y < current_vpos){
  532.      Dimension offset = current_vpos - tree_const->tree.y;
  533.      for(i = 0; i < tree_const->tree.n_sub_nodes; i++)
  534.        shift_subtree(tree_const->tree.sub_nodes[i], offset);
  535.     /*
  536.      * Adjust the next available space at all levels below
  537.      * the current level.
  538.      */
  539.      for(i = level + 1; i <= depth; i++){
  540.        Position pos = current_position(tw->tree.vertical, i);
  541.        set_current_position(tw->tree.vertical, i, pos+offset);
  542.      }
  543.      tree_const->tree.y = current_vpos;
  544.      }
  545.    }
  546.  /*
  547.   * Record the current vertical position at this level.
  548.   */
  549.   set_current_position(tw->tree.vertical, level,
  550.                        tw->tree.v_min_space + 
  551.                        tree_const->tree.y + w->core.height);
  552.   return (MAX(depth, level));
  553. }
  554.  
  555. static void shift_subtree(w, offset)
  556.      Widget     w;
  557.      Dimension  offset;
  558. {
  559.   int             i;
  560.   TreeConstraints tree_const = TREE_CONSTRAINT(w);
  561.   /*
  562.    * Shift the node by the offset.
  563.    */
  564.   tree_const->tree.y += offset; 
  565.   /*
  566.    * Shift each sub-node into place.
  567.    */
  568.   for(i=0; i< tree_const->tree.n_sub_nodes; i++)
  569.     shift_subtree(tree_const->tree.sub_nodes[i], offset);
  570. }
  571.  
  572. static void set_positions(tw, w, level)
  573.      XsTreeWidget tw;
  574.      Widget       w;
  575.      int          level;
  576. {
  577.  int               i;
  578.  Dimension         replyWidth = 0, replyHeight = 0;
  579.  XtGeometryResult  result;
  580.   
  581.  if(w){
  582.   TreeConstraints tree_const = TREE_CONSTRAINT(w);
  583.  /*
  584.   * Add up the sum of the width's of all nodes to this 
  585.   * depth, and use it as the x position.
  586.   */
  587.   tree_const->tree.x = (level * tw->tree.h_min_space) + 
  588.                 sum_of_positions(tw->tree.horizontal, level);
  589.  /*
  590.   * Move the widget into position.
  591.   */
  592.   XtMoveWidget (w, tree_const->tree.x, tree_const->tree.y);
  593.  /*
  594.   * If the widget position plus its width or height doesn't
  595.   * fit in the tree, ask if the tree can be resized.
  596.   */
  597.   if(tw->core.width < tree_const->tree.x + w->core.width ||
  598.      tw->core.height < tree_const->tree.y + w->core.height){
  599.     result = 
  600.       XtMakeResizeRequest(tw, MAX(tw->core.width, 
  601.                                   tree_const->tree.x + 
  602.                                   w->core.width),
  603.                               MAX(tw->core.height, 
  604.                                   tree_const->tree.y + 
  605.                                   w->core.height),
  606.                           &replyWidth, &replyHeight);
  607.     /*
  608.      * Accept any compromise.
  609.      */
  610.      if (result == XtGeometryAlmost)
  611.        XtMakeResizeRequest (tw, replyWidth, replyHeight, 
  612.                              NULL, NULL);
  613.   }
  614.  /*
  615.   * Set the positions of all sub_nodes.
  616.   */
  617.   for(i=0; i< tree_const->tree.n_sub_nodes;i++)
  618.     set_positions(tw, tree_const->tree.sub_nodes[i], level+1);
  619.   }
  620. }
  621.  
  622. static TreeOffsetPtr create_offset(size)
  623.    long size;
  624. {
  625.  TreeOffsetPtr  offset = 
  626.                  (TreeOffsetPtr) XtMalloc(sizeof(TreeOffset));
  627.  offset->size = size;
  628.  offset->array = 
  629.              (Dimension *) XtMalloc(size * sizeof(Dimension));
  630.  return (offset);
  631. }
  632.  
  633. static void reset(offset)
  634.    TreeOffsetPtr offset;
  635. {
  636.   long i;
  637.   for(i=0; i< offset->size; i++)
  638.     offset->array[i] = 0;
  639. }
  640.  
  641. static Position current_position(offset, position)
  642.    TreeOffsetPtr  offset;
  643.    long          position;
  644. {
  645.   if(position >= offset->size)
  646.     return (0);
  647.   return (offset->array[position]);
  648.  }
  649.  
  650. static void set_current_position(offset, index, value)
  651.    TreeOffsetPtr offset;
  652.    int           index;
  653.    Dimension     value;
  654. {
  655.  if(index >= offset->size){
  656.    offset->size = index + index / 2;
  657.    offset->array =
  658.     (Dimension *) XtRealloc(offset->array, 
  659.                             offset->size * sizeof(Dimension));
  660.  }
  661.  offset->array[index] = value;
  662. }
  663.  
  664. static Position sum_of_positions(offset, index)
  665.    TreeOffsetPtr  offset;
  666.    long           index;
  667. {
  668.   int    i;
  669.   Position  sum  = 0;
  670.   long      stop = index;
  671.   if(index > offset->size) 
  672.     stop = offset->size;
  673.   for (i=0;i < stop; i++)
  674.     sum += offset->array[i];
  675.   return (sum);
  676. }
  677.  
  678. @EOF
  679.  
  680. chmod 644 Tree.c
  681.  
  682. echo x - Tree.h
  683. cat >Tree.h <<'@EOF'
  684. /**********************************************************************************
  685.  * Tree.h: Public header file for the Tree widget
  686.   *         From:
  687.   *                   The X Window System, 
  688.   *            Programming and Applications with Xt
  689.   *                   OSF/Motif Edition
  690.   *         by
  691.   *                Douglas Young
  692.   *              Prentice Hall, 1990
  693.   *
  694.   *                 Example described on pages: 397-419
  695.   *
  696.   *
  697.   *  Copyright 1989 by Prentice Hall
  698.   *  All Rights Reserved
  699.   *
  700.   * This code is based on the OSF/Motif widget set and the X Window System
  701.   *
  702.   * Permission to use, copy, modify, and distribute this software for 
  703.   * any purpose and without fee is hereby granted, provided that the above
  704.   * copyright notice appear in all copies and that both the copyright notice
  705.   * and this permission notice appear in supporting documentation.
  706.   *
  707.   * Prentice Hall and the author disclaim all warranties with regard to 
  708.   * this software, including all implied warranties of merchantability and fitness.
  709.   * In no event shall Prentice Hall or the author be liable for any special,
  710.   * indirect or cosequential damages or any damages whatsoever resulting from 
  711.   * loss of use, data or profits, whether in an action of contract, negligence 
  712.   * or other tortious action, arising out of or in connection with the use 
  713.   * or performance of this software.
  714.   *
  715.   * Open Software Foundation is a trademark of The Open Software Foundation, Inc.
  716.   * OSF is a trademark of Open Software Foundation, Inc.
  717.   * OSF/Motif is a trademark of Open Software Foundation, Inc.
  718.   * Motif is a trademark of Open Software Foundation, Inc.
  719.   * DEC is a registered trademark of Digital Equipment Corporation
  720.   * HP is a registered trademark of the Hewlett Packard Company
  721.   * DIGITAL is a registered trademark of Digital Equipment Corporation
  722.   * X Window System is a trademark of the Massachusetts Institute of Technology
  723.   **********************************************************************************/
  724.  
  725.  
  726.  
  727. #ifndef TREE_H
  728. #define TREE_H
  729.  
  730. extern WidgetClass  XstreeWidgetClass;
  731.  
  732. typedef struct _XsTreeClassRec *XsTreeWidgetClass;
  733. typedef struct _XsTreeRec      *XsTreeWidget;
  734.  
  735. #define XtNhorizontalSpace    "horizontalSpace"
  736. #define XtNverticalSpace      "verticalSpace"
  737. #define XtCPad                "Pad"
  738. #define XtNsuperNode          "superNode"
  739. #define XtCSuperNode          "SuperNode"
  740.  
  741. #endif TREE_H
  742. @EOF
  743.  
  744. chmod 644 Tree.h
  745.  
  746. echo x - TreeP.h
  747. cat >TreeP.h <<'@EOF'
  748. /**********************************************************************************
  749.  * TreeP.h: Private header file for the Tree widget
  750.   *         From:
  751.   *                   The X Window System, 
  752.   *            Programming and Applications with Xt
  753.   *                   OSF/Motif Edition
  754.   *         by
  755.   *                Douglas Young
  756.   *              Prentice Hall, 1990
  757.   *
  758.   *                 Example described on pages: 397-419
  759.   *
  760.   *
  761.   *  Copyright 1989 by Prentice Hall
  762.   *  All Rights Reserved
  763.   *
  764.   * This code is based on the OSF/Motif widget set and the X Window System
  765.   *
  766.   * Permission to use, copy, modify, and distribute this software for 
  767.   * any purpose and without fee is hereby granted, provided that the above
  768.   * copyright notice appear in all copies and that both the copyright notice
  769.   * and this permission notice appear in supporting documentation.
  770.   *
  771.   * Prentice Hall and the author disclaim all warranties with regard to 
  772.   * this software, including all implied warranties of merchantability and fitness.
  773.   * In no event shall Prentice Hall or the author be liable for any special,
  774.   * indirect or cosequential damages or any damages whatsoever resulting from 
  775.   * loss of use, data or profits, whether in an action of contract, negligence 
  776.   * or other tortious action, arising out of or in connection with the use 
  777.   * or performance of this software.
  778.   *
  779.   * Open Software Foundation is a trademark of The Open Software Foundation, Inc.
  780.   * OSF is a trademark of Open Software Foundation, Inc.
  781.   * OSF/Motif is a trademark of Open Software Foundation, Inc.
  782.   * Motif is a trademark of Open Software Foundation, Inc.
  783.   * DEC is a registered trademark of Digital Equipment Corporation
  784.   * HP is a registered trademark of the Hewlett Packard Company
  785.   * DIGITAL is a registered trademark of Digital Equipment Corporation
  786.   * X Window System is a trademark of the Massachusetts Institute of Technology
  787.   **********************************************************************************/
  788.  
  789.  
  790. #ifndef TREEP_H
  791. #define TREEP_H
  792. typedef struct _XsTreeClassPart {
  793.     int         ignore;
  794. } XsTreeClassPart;
  795.  
  796. typedef struct _XsTreeClassRec {
  797.     CoreClassPart       core_class;
  798.     CompositeClassPart  composite_class;
  799.     ConstraintClassPart constraint_class;
  800.     XsTreeClassPart     tree_class;
  801. } XsTreeClassRec;
  802.  
  803. extern XsTreeClassRec XstreeClassRec;
  804.  
  805. typedef struct {
  806.     Dimension  *array;
  807.     int         size;
  808.   }  TreeOffset, *TreeOffsetPtr;
  809.  
  810. typedef struct {
  811.     Dimension      h_min_space;
  812.     Dimension      v_min_space;
  813.     Pixel          foreground;
  814.     GC             gc;
  815.     TreeOffsetPtr  horizontal;
  816.     TreeOffsetPtr  vertical;
  817.     Widget         tree_root;
  818. } XsTreePart;
  819.  
  820.  
  821. typedef struct _XsTreeRec {
  822.     CorePart        core;
  823.     CompositePart   composite;
  824.     ConstraintPart  constraint;
  825.     XsTreePart      tree;
  826. }  XsTreeRec;
  827.  
  828.  
  829.  
  830. typedef struct _TreeConstraintsPart {
  831.   Widget        super_node;
  832.   WidgetList    sub_nodes;
  833.   long          n_sub_nodes;
  834.   long          max_sub_nodes;
  835.   Position      x, y;
  836. } TreeConstraintsPart;
  837.  
  838. typedef struct _TreeConstraintsRec {
  839.    TreeConstraintsPart tree;
  840. } TreeConstraintsRec, *TreeConstraints;
  841.  
  842.  
  843. #define TREE_CONSTRAINT(w) \
  844.                    ((TreeConstraints)((w)->core.constraints))
  845.  
  846. #endif TREEP_H
  847.  
  848.  
  849.  
  850. @EOF
  851.  
  852. chmod 644 TreeP.h
  853.  
  854. exit 0
  855.  
  856. dan
  857. ----------------------------------------------------
  858. O'Reilly && Associates   argv@sun.com / argv@ora.com
  859. Opinions expressed reflect those of the author only.
  860.