00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #include <X11/IntrinsicP.h>
00054 #include <X11/StringDefs.h>
00055 #include <X11/Xaw3d/XawInit.h>
00056 #include <X11/Xaw3d/Cardinals.h>
00057 #include <X11/Xaw3d/TreeP.h>
00058
00059 #define IsHorizontal(tw) ((tw)->tree.gravity == WestGravity || \
00060 (tw)->tree.gravity == EastGravity)
00061
00062
00063
00064 static void ClassInitialize();
00065 static void Initialize();
00066 static void ConstraintInitialize();
00067 static void ConstraintDestroy();
00068 static Boolean ConstraintSetValues();
00069 static void Destroy();
00070 static Boolean SetValues();
00071 static XtGeometryResult GeometryManager();
00072 static void ChangeManaged();
00073 static void Redisplay();
00074 static XtGeometryResult QueryGeometry();
00075
00076
00077 static void insert_node();
00078 static void delete_node();
00079 static void layout_tree();
00080
00081
00082
00083
00084
00085 static XtResource resources[] = {
00086 { XtNautoReconfigure, XtCAutoReconfigure, XtRBoolean, sizeof (Boolean),
00087 XtOffsetOf(TreeRec, tree.auto_reconfigure), XtRImmediate,
00088 (XtPointer) FALSE },
00089 { XtNhSpace, XtCHSpace, XtRDimension, sizeof (Dimension),
00090 XtOffsetOf(TreeRec, tree.hpad), XtRImmediate, (XtPointer) 0 },
00091 { XtNvSpace, XtCVSpace, XtRDimension, sizeof (Dimension),
00092 XtOffsetOf(TreeRec, tree.vpad), XtRImmediate, (XtPointer) 0 },
00093 { XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel),
00094 XtOffsetOf(TreeRec, tree.foreground), XtRString,
00095 XtDefaultForeground},
00096 { XtNlineWidth, XtCLineWidth, XtRDimension, sizeof (Dimension),
00097 XtOffsetOf(TreeRec, tree.line_width), XtRImmediate, (XtPointer) 0 },
00098 { XtNgravity, XtCGravity, XtRGravity, sizeof (XtGravity),
00099 XtOffsetOf(TreeRec, tree.gravity), XtRImmediate,
00100 (XtPointer) WestGravity },
00101 };
00102
00103
00104
00105
00106
00107 static XtResource treeConstraintResources[] = {
00108 { XtNtreeParent, XtCTreeParent, XtRWidget, sizeof (Widget),
00109 XtOffsetOf(TreeConstraintsRec, tree.parent), XtRImmediate, NULL },
00110 { XtNtreeGC, XtCTreeGC, XtRGC, sizeof(GC),
00111 XtOffsetOf(TreeConstraintsRec, tree.gc), XtRImmediate, NULL },
00112 };
00113
00114
00115 TreeClassRec treeClassRec = {
00116 {
00117
00118 (WidgetClass) &constraintClassRec,
00119 "Tree",
00120 sizeof(TreeRec),
00121 ClassInitialize,
00122 NULL,
00123 FALSE,
00124 Initialize,
00125 NULL,
00126 XtInheritRealize,
00127 NULL,
00128 0,
00129 resources,
00130 XtNumber(resources),
00131 NULLQUARK,
00132 TRUE,
00133 TRUE,
00134 TRUE,
00135 TRUE,
00136 Destroy,
00137 NULL,
00138 Redisplay,
00139 SetValues,
00140 NULL,
00141 XtInheritSetValuesAlmost,
00142 NULL,
00143 NULL,
00144 XtVersion,
00145 NULL,
00146 NULL,
00147 QueryGeometry,
00148 NULL,
00149 NULL,
00150 },
00151 {
00152
00153 GeometryManager,
00154 ChangeManaged,
00155 XtInheritInsertChild,
00156 XtInheritDeleteChild,
00157 NULL,
00158 },
00159 {
00160
00161 treeConstraintResources,
00162 XtNumber(treeConstraintResources),
00163 sizeof(TreeConstraintsRec),
00164 ConstraintInitialize,
00165 ConstraintDestroy,
00166 ConstraintSetValues,
00167 NULL,
00168 },
00169 {
00170
00171 0,
00172 }
00173 };
00174
00175 WidgetClass treeWidgetClass = (WidgetClass) &treeClassRec;
00176
00177
00178
00179
00180
00181
00182
00183
00184 static void initialize_dimensions (listp, sizep, n)
00185 Dimension **listp;
00186 int *sizep;
00187 int n;
00188 {
00189 int i;
00190 Dimension *l;
00191
00192 if (!*listp) {
00193 *listp = (Dimension *) XtCalloc ((unsigned int) n,
00194 (unsigned int) sizeof(Dimension));
00195 *sizep = ((*listp) ? n : 0);
00196 return;
00197 }
00198 if (n > *sizep) {
00199 *listp = (Dimension *) XtRealloc((char *) *listp,
00200 (unsigned int) (n*sizeof(Dimension)));
00201 if (!*listp) {
00202 *sizep = 0;
00203 return;
00204 }
00205 for (i = *sizep, l = (*listp) + i; i < n; i++, l++) *l = 0;
00206 *sizep = n;
00207 }
00208 return;
00209 }
00210
00211 static GC get_tree_gc (w)
00212 TreeWidget w;
00213 {
00214 XtGCMask valuemask = GCBackground | GCForeground;
00215 XGCValues values;
00216
00217 values.background = w->core.background_pixel;
00218 values.foreground = w->tree.foreground;
00219 if (w->tree.line_width != 0) {
00220 valuemask |= GCLineWidth;
00221 values.line_width = w->tree.line_width;
00222 }
00223
00224 return XtGetGC ((Widget) w, valuemask, &values);
00225 }
00226
00227 static void insert_node (parent, node)
00228 Widget parent, node;
00229 {
00230 TreeConstraints pc;
00231 TreeConstraints nc = TREE_CONSTRAINT(node);
00232 int nindex;
00233
00234 nc->tree.parent = parent;
00235
00236 if (parent == NULL) return;
00237
00238
00239
00240
00241
00242 pc = TREE_CONSTRAINT(parent);
00243 nindex = pc->tree.n_children;
00244
00245 if (pc->tree.n_children == pc->tree.max_children) {
00246 pc->tree.max_children += (pc->tree.max_children / 2) + 2;
00247 pc->tree.children = (WidgetList) XtRealloc ((char *)pc->tree.children,
00248 (unsigned int)
00249 ((pc->tree.max_children) *
00250 sizeof(Widget)));
00251 }
00252
00253
00254
00255
00256
00257 pc->tree.children[nindex] = node;
00258 pc->tree.n_children++;
00259 }
00260
00261 static void delete_node (parent, node)
00262 Widget parent, node;
00263 {
00264 TreeConstraints pc;
00265 int pos, i;
00266
00267
00268
00269
00270 if (!parent) return;
00271
00272 pc = TREE_CONSTRAINT(parent);
00273
00274
00275
00276
00277 for (pos = 0; pos < pc->tree.n_children; pos++)
00278 if (pc->tree.children[pos] == node) break;
00279
00280 if (pos == pc->tree.n_children) return;
00281
00282
00283
00284
00285 pc->tree.n_children--;
00286
00287
00288
00289
00290
00291 for (i = pos; i < pc->tree.n_children; i++)
00292 pc->tree.children[i] = pc->tree.children[i+1];
00293
00294 pc->tree.children[pc->tree.n_children]=0;
00295 }
00296
00297 static void check_gravity (tw, grav)
00298 TreeWidget tw;
00299 XtGravity grav;
00300 {
00301 switch (tw->tree.gravity) {
00302 case WestGravity: case NorthGravity: case EastGravity: case SouthGravity:
00303 break;
00304 default:
00305 tw->tree.gravity = grav;
00306 break;
00307 }
00308 }
00309
00310
00311
00312
00313
00314
00315
00316
00317 static void ClassInitialize ()
00318 {
00319 XawInitializeWidgetSet();
00320 XtAddConverter (XtRString, XtRGravity, XmuCvtStringToGravity,
00321 (XtConvertArgList) NULL, (Cardinal) 0);
00322 }
00323
00324
00325
00326 static void Initialize (grequest, gnew, args, num_args)
00327 Widget grequest, gnew;
00328 ArgList args;
00329 Cardinal *num_args;
00330 {
00331 TreeWidget request = (TreeWidget) grequest, new = (TreeWidget) gnew;
00332 Arg arglist[2];
00333
00334
00335
00336
00337
00338 if (request->core.width <= 0) new->core.width = 5;
00339 if (request->core.height <= 0) new->core.height = 5;
00340
00341
00342
00343
00344 if (request->tree.hpad == 0 && request->tree.vpad == 0) {
00345 if (IsHorizontal (request)) {
00346 new->tree.hpad = TREE_HORIZONTAL_DEFAULT_SPACING;
00347 new->tree.vpad = TREE_VERTICAL_DEFAULT_SPACING;
00348 } else {
00349 new->tree.hpad = TREE_VERTICAL_DEFAULT_SPACING;
00350 new->tree.vpad = TREE_HORIZONTAL_DEFAULT_SPACING;
00351 }
00352 }
00353
00354
00355
00356
00357 new->tree.gc = get_tree_gc (new);
00358
00359
00360
00361
00362 new->tree.tree_root = (Widget) NULL;
00363 XtSetArg(arglist[0], XtNwidth, 1);
00364 XtSetArg(arglist[1], XtNheight, 1);
00365 new->tree.tree_root = XtCreateWidget ("root", widgetClass, gnew,
00366 arglist,TWO);
00367
00368
00369
00370
00371 new->tree.largest = NULL;
00372 new->tree.n_largest = 0;
00373 initialize_dimensions (&new->tree.largest, &new->tree.n_largest,
00374 TREE_INITIAL_DEPTH);
00375
00376
00377
00378
00379 check_gravity (new, WestGravity);
00380 }
00381
00382
00383
00384 static void ConstraintInitialize (request, new, args, num_args)
00385 Widget request, new;
00386 ArgList args;
00387 Cardinal *num_args;
00388 {
00389 TreeConstraints tc = TREE_CONSTRAINT(new);
00390 TreeWidget tw = (TreeWidget) new->core.parent;
00391
00392
00393
00394
00395 tc->tree.n_children = 0;
00396 tc->tree.max_children = 0;
00397 tc->tree.children = (Widget *) NULL;
00398 tc->tree.x = tc->tree.y = 0;
00399 tc->tree.bbsubwidth = 0;
00400 tc->tree.bbsubheight = 0;
00401
00402
00403
00404
00405
00406
00407
00408 if (tc->tree.parent)
00409 insert_node (tc->tree.parent, new);
00410 else if (tw->tree.tree_root)
00411 insert_node (tw->tree.tree_root, new);
00412 }
00413
00414
00415
00416 static Boolean SetValues (gcurrent, grequest, gnew, args, num_args)
00417 Widget gcurrent, grequest, gnew;
00418 ArgList args;
00419 Cardinal *num_args;
00420 {
00421 TreeWidget current = (TreeWidget) gcurrent, new = (TreeWidget) gnew;
00422 Boolean redraw = FALSE;
00423
00424
00425
00426
00427
00428 if (new->tree.foreground != current->tree.foreground ||
00429 new->core.background_pixel != current->core.background_pixel ||
00430 new->tree.line_width != current->tree.line_width) {
00431 XtReleaseGC (gnew, new->tree.gc);
00432 new->tree.gc = get_tree_gc (new);
00433 redraw = TRUE;
00434 }
00435
00436
00437
00438
00439
00440
00441 if (new->tree.gravity != current->tree.gravity) {
00442 check_gravity (new, current->tree.gravity);
00443 }
00444
00445 if (IsHorizontal(new) != IsHorizontal(current)) {
00446 if (new->tree.vpad == current->tree.vpad &&
00447 new->tree.hpad == current->tree.hpad) {
00448 new->tree.vpad = current->tree.hpad;
00449 new->tree.hpad = current->tree.vpad;
00450 }
00451 }
00452
00453 if (new->tree.vpad != current->tree.vpad ||
00454 new->tree.hpad != current->tree.hpad ||
00455 new->tree.gravity != current->tree.gravity) {
00456 layout_tree (new, TRUE);
00457 redraw = FALSE;
00458 }
00459 return redraw;
00460 }
00461
00462
00463
00464 static Boolean ConstraintSetValues (current, request, new, args, num_args)
00465 Widget current, request, new;
00466 ArgList args;
00467 Cardinal *num_args;
00468 {
00469 TreeConstraints newc = TREE_CONSTRAINT(new);
00470 TreeConstraints curc = TREE_CONSTRAINT(current);
00471 TreeWidget tw = (TreeWidget) new->core.parent;
00472
00473
00474
00475
00476
00477
00478 if (curc->tree.parent != newc->tree.parent){
00479 if (curc->tree.parent)
00480 delete_node (curc->tree.parent, new);
00481 if (newc->tree.parent)
00482 insert_node(newc->tree.parent, new);
00483
00484
00485
00486
00487
00488 if (XtIsRealized((Widget)tw))
00489 layout_tree (tw, FALSE);
00490 }
00491 return False;
00492 }
00493
00494
00495 static void ConstraintDestroy (w)
00496 Widget w;
00497 {
00498 TreeConstraints tc = TREE_CONSTRAINT(w);
00499 TreeWidget tw = (TreeWidget) XtParent(w);
00500 int i;
00501
00502
00503
00504
00505
00506
00507 if (tw->tree.tree_root == w) {
00508 if (tc->tree.n_children > 0)
00509 tw->tree.tree_root = tc->tree.children[0];
00510 else
00511 tw->tree.tree_root = NULL;
00512 }
00513
00514 delete_node (tc->tree.parent, (Widget) w);
00515 for (i = 0; i< tc->tree.n_children; i++)
00516 insert_node (tc->tree.parent, tc->tree.children[i]);
00517
00518 layout_tree ((TreeWidget) (w->core.parent), FALSE);
00519 }
00520
00521
00522 static XtGeometryResult GeometryManager (w, request, reply)
00523 Widget w;
00524 XtWidgetGeometry *request;
00525 XtWidgetGeometry *reply;
00526 {
00527
00528 TreeWidget tw = (TreeWidget) w->core.parent;
00529
00530
00531
00532
00533 if ((request->request_mode & CWX && request->x!=w->core.x)
00534 ||(request->request_mode & CWY && request->y!=w->core.y))
00535 return (XtGeometryNo);
00536
00537
00538
00539
00540
00541 if (request->request_mode & CWWidth)
00542 w->core.width = request->width;
00543 if (request->request_mode & CWHeight)
00544 w->core.height = request->height;
00545 if (request->request_mode & CWBorderWidth)
00546 w->core.border_width = request->border_width;
00547
00548 if (tw->tree.auto_reconfigure) layout_tree (tw, FALSE);
00549 return (XtGeometryYes);
00550 }
00551
00552 static void ChangeManaged (gw)
00553 Widget gw;
00554 {
00555 layout_tree ((TreeWidget) gw, FALSE);
00556 }
00557
00558
00559 static void Destroy (gw)
00560 Widget gw;
00561 {
00562 TreeWidget w = (TreeWidget) gw;
00563
00564 XtReleaseGC (gw, w->tree.gc);
00565 if (w->tree.largest) XtFree ((char *) w->tree.largest);
00566 }
00567
00568
00569
00570 static void Redisplay (gw, event, region)
00571 Widget gw;
00572 XEvent *event;
00573 Region region;
00574 {
00575 TreeWidget tw = (TreeWidget) gw;
00576
00577
00578
00579
00580 if (tw->core.visible) {
00581 int i, j;
00582 Display *dpy = XtDisplay (tw);
00583 Window w = XtWindow (tw);
00584
00585 for (i = 0; i < tw->composite.num_children; i++) {
00586 Widget child = tw->composite.children[i];
00587 TreeConstraints tc = TREE_CONSTRAINT(child);
00588
00589
00590
00591
00592 if (child != tw->tree.tree_root && tc->tree.n_children) {
00593 int srcx = child->core.x + child->core.border_width;
00594 int srcy = child->core.y + child->core.border_width;
00595
00596 switch (tw->tree.gravity) {
00597 case WestGravity:
00598 srcx += child->core.width + child->core.border_width;
00599
00600 case EastGravity:
00601 srcy += child->core.height / 2;
00602 break;
00603
00604 case NorthGravity:
00605 srcy += child->core.height + child->core.border_width;
00606
00607 case SouthGravity:
00608 srcx += child->core.width / 2;
00609 break;
00610 }
00611
00612 for (j = 0; j < tc->tree.n_children; j++) {
00613 Widget k = tc->tree.children[j];
00614 GC gc = (tc->tree.gc ? tc->tree.gc : tw->tree.gc);
00615
00616 switch (tw->tree.gravity) {
00617 case WestGravity:
00618
00619
00620
00621 XDrawLine (dpy, w, gc, srcx, srcy,
00622 (int) k->core.x,
00623 (k->core.y + ((int) k->core.border_width) +
00624 ((int) k->core.height) / 2));
00625 break;
00626
00627 case NorthGravity:
00628
00629
00630
00631 XDrawLine (dpy, w, gc, srcx, srcy,
00632 (k->core.x + ((int) k->core.border_width) +
00633 ((int) k->core.width) / 2),
00634 (int) k->core.y);
00635 break;
00636
00637 case EastGravity:
00638
00639
00640
00641 XDrawLine (dpy, w, gc, srcx, srcy,
00642 (k->core.x +
00643 (((int) k->core.border_width) << 1) +
00644 (int) k->core.width),
00645 (k->core.y + ((int) k->core.border_width) +
00646 ((int) k->core.height) / 2));
00647 break;
00648
00649 case SouthGravity:
00650
00651
00652
00653 XDrawLine (dpy, w, gc, srcx, srcy,
00654 (k->core.x + ((int) k->core.border_width) +
00655 ((int) k->core.width) / 2),
00656 (k->core.y +
00657 (((int) k->core.border_width) << 1) +
00658 (int) k->core.height));
00659 break;
00660 }
00661 }
00662 }
00663 }
00664 }
00665 }
00666
00667 static XtGeometryResult QueryGeometry (w, intended, preferred)
00668 Widget w;
00669 XtWidgetGeometry *intended, *preferred;
00670 {
00671 TreeWidget tw = (TreeWidget) w;
00672
00673 preferred->request_mode = (CWWidth | CWHeight);
00674 preferred->width = tw->tree.maxwidth;
00675 preferred->height = tw->tree.maxheight;
00676
00677 if (((intended->request_mode & (CWWidth | CWHeight)) ==
00678 (CWWidth | CWHeight)) &&
00679 intended->width == preferred->width &&
00680 intended->height == preferred->height)
00681 return XtGeometryYes;
00682 else if (preferred->width == w->core.width &&
00683 preferred->height == w->core.height)
00684 return XtGeometryNo;
00685 else
00686 return XtGeometryAlmost;
00687 }
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701 static void compute_bounding_box_subtree (tree, w, depth)
00702 TreeWidget tree;
00703 Widget w;
00704 int depth;
00705 {
00706 TreeConstraints tc = TREE_CONSTRAINT(w);
00707 int i;
00708 Bool horiz = IsHorizontal (tree);
00709 Dimension newwidth, newheight;
00710 Dimension bw2 = w->core.border_width * 2;
00711
00712
00713
00714
00715 if (depth >= tree->tree.n_largest) {
00716 initialize_dimensions (&tree->tree.largest,
00717 &tree->tree.n_largest, depth + 1);
00718 }
00719 newwidth = ((horiz ? w->core.width : w->core.height) + bw2);
00720 if (tree->tree.largest[depth] < newwidth)
00721 tree->tree.largest[depth] = newwidth;
00722
00723
00724
00725
00726
00727 tc->tree.bbwidth = w->core.width + bw2;
00728 tc->tree.bbheight = w->core.height + bw2;
00729
00730 if (tc->tree.n_children == 0) return;
00731
00732
00733
00734
00735
00736
00737 newwidth = 0;
00738 newheight = 0;
00739 for (i = 0; i < tc->tree.n_children; i++) {
00740 Widget child = tc->tree.children[i];
00741 TreeConstraints cc = TREE_CONSTRAINT(child);
00742
00743 compute_bounding_box_subtree (tree, child, depth + 1);
00744
00745 if (horiz) {
00746 if (newwidth < cc->tree.bbwidth) newwidth = cc->tree.bbwidth;
00747 newheight += tree->tree.vpad + cc->tree.bbheight;
00748 } else {
00749 if (newheight < cc->tree.bbheight) newheight = cc->tree.bbheight;
00750 newwidth += tree->tree.hpad + cc->tree.bbwidth;
00751 }
00752 }
00753
00754
00755 tc->tree.bbsubwidth = newwidth;
00756 tc->tree.bbsubheight = newheight;
00757
00758
00759
00760
00761
00762 if (horiz) {
00763 tc->tree.bbwidth += tree->tree.hpad + newwidth;
00764 newheight -= tree->tree.vpad;
00765 if (newheight > tc->tree.bbheight) tc->tree.bbheight = newheight;
00766 } else {
00767 tc->tree.bbheight += tree->tree.vpad + newheight;
00768 newwidth -= tree->tree.hpad;
00769 if (newwidth > tc->tree.bbwidth) tc->tree.bbwidth = newwidth;
00770 }
00771 }
00772
00773
00774 static void set_positions (tw, w, level)
00775 TreeWidget tw;
00776 Widget w;
00777 int level;
00778 {
00779 int i;
00780
00781 if (w) {
00782 TreeConstraints tc = TREE_CONSTRAINT(w);
00783
00784 if (level > 0) {
00785
00786
00787
00788 switch (tw->tree.gravity) {
00789 case EastGravity:
00790 tc->tree.x = (((Position) tw->tree.maxwidth) -
00791 ((Position) w->core.width) - tc->tree.x);
00792 break;
00793
00794 case SouthGravity:
00795 tc->tree.y = (((Position) tw->tree.maxheight) -
00796 ((Position) w->core.height) - tc->tree.y);
00797 break;
00798 }
00799
00800
00801
00802
00803 XtMoveWidget (w, tc->tree.x, tc->tree.y);
00804 }
00805
00806
00807
00808
00809 for (i = 0; i < tc->tree.n_children; i++)
00810 set_positions (tw, tc->tree.children[i], level + 1);
00811 }
00812 }
00813
00814
00815 static void arrange_subtree (tree, w, depth, x, y)
00816 TreeWidget tree;
00817 Widget w;
00818 int depth;
00819 Position x, y;
00820 {
00821 TreeConstraints tc = TREE_CONSTRAINT(w);
00822 TreeConstraints firstcc, lastcc;
00823 int i;
00824 int newx, newy;
00825 Bool horiz = IsHorizontal (tree);
00826 Widget child = NULL;
00827 Dimension tmp;
00828 Dimension bw2 = w->core.border_width * 2;
00829 Bool relayout = True;
00830
00831
00832
00833
00834
00835 tc->tree.x = x;
00836 tc->tree.y = y;
00837
00838 if (horiz) {
00839 int myh = (w->core.height + bw2);
00840
00841 if (myh > (int)tc->tree.bbsubheight) {
00842 y += (myh - (int)tc->tree.bbsubheight) / 2;
00843 relayout = False;
00844 }
00845 } else {
00846 int myw = (w->core.width + bw2);
00847
00848 if (myw > (int)tc->tree.bbsubwidth) {
00849 x += (myw - (int)tc->tree.bbsubwidth) / 2;
00850 relayout = False;
00851 }
00852 }
00853
00854 if ((tmp = ((Dimension) x) + tc->tree.bbwidth) > tree->tree.maxwidth)
00855 tree->tree.maxwidth = tmp;
00856 if ((tmp = ((Dimension) y) + tc->tree.bbheight) > tree->tree.maxheight)
00857 tree->tree.maxheight = tmp;
00858
00859 if (tc->tree.n_children == 0) return;
00860
00861
00862
00863
00864
00865
00866 if (horiz) {
00867 newx = x + tree->tree.largest[depth];
00868 if (depth > 0) newx += tree->tree.hpad;
00869 newy = y;
00870 } else {
00871 newx = x;
00872 newy = y + tree->tree.largest[depth];
00873 if (depth > 0) newy += tree->tree.vpad;
00874 }
00875
00876 for (i = 0; i < tc->tree.n_children; i++) {
00877 TreeConstraints cc;
00878
00879 child = tc->tree.children[i];
00880 cc = TREE_CONSTRAINT(child);
00881
00882 arrange_subtree (tree, child, depth + 1, newx, newy);
00883 if (horiz) {
00884 newy += tree->tree.vpad + cc->tree.bbheight;
00885 } else {
00886 newx += tree->tree.hpad + cc->tree.bbwidth;
00887 }
00888 }
00889
00890
00891
00892
00893 if (relayout) {
00894 Position adjusted;
00895 firstcc = TREE_CONSTRAINT (tc->tree.children[0]);
00896 lastcc = TREE_CONSTRAINT (child);
00897
00898
00899
00900
00901
00902 if (horiz) {
00903 tc->tree.x = x;
00904 adjusted = firstcc->tree.y +
00905 ((lastcc->tree.y + (Position) child->core.height +
00906 (Position) child->core.border_width * 2 -
00907 firstcc->tree.y - (Position) w->core.height -
00908 (Position) w->core.border_width * 2 + 1) / 2);
00909 if (adjusted > tc->tree.y) tc->tree.y = adjusted;
00910 } else {
00911 adjusted = firstcc->tree.x +
00912 ((lastcc->tree.x + (Position) child->core.width +
00913 (Position) child->core.border_width * 2 -
00914 firstcc->tree.x - (Position) w->core.width -
00915 (Position) w->core.border_width * 2 + 1) / 2);
00916 if (adjusted > tc->tree.x) tc->tree.x = adjusted;
00917 tc->tree.y = y;
00918 }
00919 }
00920 }
00921
00922 static void set_tree_size (tw, insetvalues, width, height)
00923 TreeWidget tw;
00924 Boolean insetvalues;
00925 Dimension width, height;
00926 {
00927 if (insetvalues) {
00928 tw->core.width = width;
00929 tw->core.height = height;
00930 } else {
00931 Dimension replyWidth = 0, replyHeight = 0;
00932 XtGeometryResult result = XtMakeResizeRequest ((Widget) tw,
00933 width, height,
00934 &replyWidth,
00935 &replyHeight);
00936
00937
00938
00939 if (result == XtGeometryAlmost)
00940 XtMakeResizeRequest ((Widget) tw, replyWidth, replyHeight,
00941 (Dimension *) NULL, (Dimension *) NULL);
00942 }
00943 return;
00944 }
00945
00946 static void layout_tree (tw, insetvalues)
00947 TreeWidget tw;
00948 Boolean insetvalues;
00949 {
00950 int i;
00951 Dimension *dp;
00952
00953
00954
00955
00956
00957
00958
00959 if (tw->tree.tree_root == NULL)
00960 return;
00961
00962 tw->tree.maxwidth = tw->tree.maxheight = 0;
00963 for (i = 0, dp = tw->tree.largest; i < tw->tree.n_largest; i++, dp++)
00964 *dp = 0;
00965 initialize_dimensions (&tw->tree.largest, &tw->tree.n_largest,
00966 tw->tree.n_largest);
00967 compute_bounding_box_subtree (tw, tw->tree.tree_root, 0);
00968
00969
00970
00971
00972
00973
00974 arrange_subtree (tw, tw->tree.tree_root, 0, 0, 0);
00975
00976
00977
00978
00979 set_tree_size (tw, insetvalues, tw->tree.maxwidth, tw->tree.maxheight);
00980 set_positions (tw, tw->tree.tree_root, 0);
00981
00982
00983
00984
00985 if (XtIsRealized ((Widget) tw)) {
00986 XClearArea (XtDisplay(tw), XtWindow((Widget)tw), 0, 0, 0, 0, True);
00987 }
00988 }
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998 void
00999 #if NeedFunctionPrototypes
01000 XawTreeForceLayout (Widget tree)
01001 #else
01002 XawTreeForceLayout (tree)
01003 Widget tree;
01004 #endif
01005 {
01006 layout_tree ((TreeWidget) tree, FALSE);
01007 }
01008