Merge branch 'master' into xcircuit-3.10
[xcircuit.git] / Xw / Form.c
blobffe09dbf6df5acfd53761a2d6f6fe74649bbbc49
1 /*************************************<+>*************************************
2 *****************************************************************************
3 **
4 ** File: Form.c
5 **
6 ** Project: X Widgets
7 **
8 ** Description: Contains code for the X Widget's Form manager.
9 **
10 *****************************************************************************
11 **
12 ** Copyright (c) 1988 by Hewlett-Packard Company
13 ** Copyright (c) 1988 by the Massachusetts Institute of Technology
14 **
15 ** Permission to use, copy, modify, and distribute this software
16 ** and its documentation for any purpose and without fee is hereby
17 ** granted, provided that the above copyright notice appear in all
18 ** copies and that both that copyright notice and this permission
19 ** notice appear in supporting documentation, and that the names of
20 ** Hewlett-Packard or M.I.T. not be used in advertising or publicity
21 ** pertaining to distribution of the software without specific, written
22 ** prior permission.
23 **
24 *****************************************************************************
25 *************************************<+>*************************************/
28 #include <stdio.h>
29 #include <string.h>
30 #include <ctype.h>
31 #include <X11/Xlib.h>
32 #include <X11/IntrinsicP.h>
33 #include <X11/Intrinsic.h>
34 #include <Xw/Xw.h>
35 #include <Xw/XwP.h>
36 #include <Xw/Form.h>
37 #include <Xw/FormP.h>
38 #include <X11/StringDefs.h>
39 #include <X11/keysymdef.h>
42 /* Constraint resource list for Form */
44 static XtResource constraintResources[] =
47 XtNxRefName, XtCXRefName, XtRString, sizeof(caddr_t),
48 XtOffset(XwFormConstraints, x_ref_name), XtRString, (caddr_t) NULL
52 XtNxRefWidget, XtCXRefWidget, XtRPointer, sizeof(caddr_t),
53 XtOffset(XwFormConstraints, x_ref_widget), XtRPointer, NULL
57 XtNxOffset, XtCXOffset, XtRInt, sizeof(int),
58 XtOffset(XwFormConstraints, x_offset), XtRString, "0"
62 XtNxAddWidth, XtCXAddWidth, XtRBoolean, sizeof(Boolean),
63 XtOffset(XwFormConstraints, x_add_width), XtRString, "False"
67 XtNxVaryOffset, XtCXVaryOffset, XtRBoolean, sizeof(Boolean),
68 XtOffset(XwFormConstraints, x_vary_offset), XtRString, "False"
72 XtNxResizable, XtCXResizable, XtRBoolean, sizeof(Boolean),
73 XtOffset(XwFormConstraints, x_resizable), XtRString, "False"
77 XtNxAttachRight, XtCXAttachRight, XtRBoolean, sizeof(Boolean),
78 XtOffset(XwFormConstraints, x_attach_right), XtRString, "False"
82 XtNxAttachOffset, XtCXAttachOffset, XtRInt, sizeof(int),
83 XtOffset(XwFormConstraints, x_attach_offset), XtRString, "0"
87 XtNyRefName, XtCYRefName, XtRString, sizeof(caddr_t),
88 XtOffset(XwFormConstraints, y_ref_name), XtRString, (caddr_t) NULL
92 XtNyRefWidget, XtCYRefWidget, XtRPointer, sizeof(caddr_t),
93 XtOffset(XwFormConstraints, y_ref_widget), XtRPointer, NULL
97 XtNyOffset, XtCYOffset, XtRInt, sizeof(int),
98 XtOffset(XwFormConstraints, y_offset), XtRString, "0"
102 XtNyAddHeight, XtCYAddHeight, XtRBoolean, sizeof(Boolean),
103 XtOffset(XwFormConstraints, y_add_height), XtRString, "False"
107 XtNyVaryOffset, XtCYVaryOffset, XtRBoolean, sizeof(Boolean),
108 XtOffset(XwFormConstraints, y_vary_offset), XtRString, "False"
112 XtNyResizable, XtCYResizable, XtRBoolean, sizeof(Boolean),
113 XtOffset(XwFormConstraints, y_resizable), XtRString, "False"
117 XtNyAttachBottom, XtCYAttachBottom, XtRBoolean, sizeof(Boolean),
118 XtOffset(XwFormConstraints, y_attach_bottom), XtRString, "False"
122 XtNyAttachOffset, XtCYAttachOffset, XtRInt, sizeof(int),
123 XtOffset(XwFormConstraints, y_attach_offset), XtRString, "0"
129 /* Static routine definitions */
131 static void Initialize();
132 static void Realize();
133 static void Resize();
134 static void Destroy();
135 static Boolean SetValues();
137 static void ChangeManaged();
138 static XtGeometryResult GeometryManager();
140 static void ConstraintInitialize();
141 static void ConstraintDestroy();
142 static Boolean ConstraintSetValues();
144 static void GetRefWidget();
145 static Widget XwFindWidget();
146 static XwFormRef * XwGetFormRef();
147 static Widget XwFindValidRef();
148 static XwFormRef * XwRefTreeSearch();
149 static XwFormRef * XwParentRefTreeSearch();
150 static void XwMakeRefs();
151 static void XwDestroyRefs();
152 static void XwProcessRefs();
153 static void XwAddRef();
154 static void XwRemoveRef();
155 static void XwFindDepthAndCount();
156 static void XwInitProcessList();
157 static void XwConstrainList();
158 static void XwFreeConstraintList();
161 /* Static global variable definitions */
163 static int depth, leaves, arrayIndex;
166 /* The Form class record */
168 XwFormClassRec XwformClassRec =
171 (WidgetClass) &XwmanagerClassRec, /* superclass */
172 "XwForm", /* class_name */
173 sizeof(XwFormRec), /* widget_size */
174 NULL, /* class_initialize */
175 NULL, /* class_part_initialize */
176 FALSE, /* class_inited */
177 (XtInitProc) Initialize, /* initialize */
178 NULL, /* initialize_hook */
179 (XtRealizeProc) Realize, /* realize */
180 NULL, /* actions */
181 0, /* num_actions */
182 NULL, /* resources */
183 0, /* num_resources */
184 NULLQUARK, /* xrm_class */
185 TRUE, /* compress_motion */
186 TRUE, /* compress_exposure */
187 TRUE, /* compress_enterleave */
188 FALSE, /* visible_interest */
189 (XtWidgetProc) Destroy, /* destroy */
190 (XtWidgetProc) Resize, /* resize */
191 NULL, /* expose */
192 (XtSetValuesFunc) SetValues, /* set_values */
193 NULL, /* set_values_hook */
194 XtInheritSetValuesAlmost, /* set_values_almost */
195 NULL, /* get_values_hook */
196 NULL, /* accept_focus */
197 XtVersion, /* version */
198 NULL, /* callback private */
199 NULL, /* tm_table */
200 NULL, /* query_geometry */
201 /* display_accelerator */ XtInheritDisplayAccelerator,
202 /* extension */ NULL
205 { /* composite class */
206 (XtGeometryHandler) GeometryManager, /* geometry_manager */
207 (XtWidgetProc) ChangeManaged, /* change_managed */
208 XtInheritInsertChild, /* insert_child */
209 XtInheritDeleteChild, /* delete_child (inherited) */
210 NULL,
213 { /* constraint class */
214 constraintResources, /* constraint resource set */
215 XtNumber(constraintResources), /* num_resources */
216 sizeof(XwFormConstraintRec), /* size of the constraint data */
217 (XtInitProc) ConstraintInitialize, /* contraint initilize proc */
218 (XtWidgetProc) ConstraintDestroy, /* contraint destroy proc */
219 (XtSetValuesFunc) ConstraintSetValues, /* contraint set values proc */
220 NULL,
223 { /* manager class */
224 (XwTraversalProc) XtInheritTraversalProc /* traversal handler */
227 { /* form class */
228 0 /* mumble */
233 WidgetClass XwformWidgetClass = (WidgetClass) &XwformClassRec;
238 /************************************************************************
240 * Initialize
241 * The main widget instance initialization routine.
243 ************************************************************************/
245 static void Initialize (request, new)
246 XwFormWidget request, new;
249 /* Initialize the tree fields to NULL */
251 new -> form.width_tree =
252 XwGetFormRef (new, NULL, 0, False, False, True, False, 0, 0, 0);
253 new -> form.height_tree =
254 XwGetFormRef (new, NULL, 0, False, False, True, False, 0, 0, 0);
257 /* Set up a geometry for the widget if it is currently 0. */
259 if (request -> core.width == 0)
260 new -> core.width += 200;
261 if (request -> core.height == 0)
262 new -> core.height += 200;
268 /************************************************************************
270 * ConstraintInitialize
271 * The main widget instance constraint initialization routine.
273 ************************************************************************/
275 static void ConstraintInitialize (request, new)
276 Widget request, new;
279 XwFormConstraintRec * constraintRec;
281 constraintRec = (XwFormConstraintRec *) new -> core.constraints;
284 /* Initialize the contraint widget sizes for later processing */
286 constraintRec -> set_x = 0;
287 constraintRec -> set_y = 0;
288 constraintRec -> set_width = 0;
289 constraintRec -> set_height = 0;
291 constraintRec -> x = new -> core.x;
292 constraintRec -> y = new -> core.y;
293 constraintRec -> width = new -> core.width;
294 constraintRec -> height = new -> core.height;
296 constraintRec -> managed = False;
299 /* Get and save copies of the names of the reference widgets */
301 GetRefWidget (&constraintRec -> x_ref_widget,
302 &constraintRec -> x_ref_name, new);
303 GetRefWidget (&constraintRec -> y_ref_widget,
304 &constraintRec -> y_ref_name, new);
311 /************************************************************************
313 * GetRefWidget
314 * Get and verify the reference widget given.
316 ************************************************************************/
318 static void GetRefWidget (widget, name, new)
319 Widget * widget;
320 char ** name;
321 Widget new;
324 if (*widget != NULL)
326 if (*name != NULL)
328 if (strcmp (*name, (char *) ((*widget) -> core.name)) != 0)
330 XtWarning
331 ("Form: The reference widget and widget name do not match.");
332 *name = (char *) (*widget) -> core.name;
335 else
336 *name = (char *) (*widget) -> core.name;
338 if ((*widget) != new -> core.parent &&
339 (*widget) -> core.parent != new -> core.parent)
341 XtWarning ("Form: The reference widget is not a child of the form");
342 XtWarning (" or the form widget.");
343 *name = new -> core.parent -> core.name;
344 *widget = new -> core.parent;
348 else if (*name != NULL)
350 if ((*widget = XwFindWidget ((CompositeWidget)(new->core.parent), *name)) == NULL)
352 XtWarning ("Form: The reference widget was not found.");
353 *name = new -> core.parent -> core.name;
354 *widget = new -> core.parent;
357 else
359 *name = new -> core.parent -> core.name;
360 *widget = new -> core.parent;
363 *name = strcpy (XtMalloc((unsigned) XwStrlen (*name) + 1), *name);
369 /************************************************************************
371 * XwFindWidget
373 ************************************************************************/
375 static Widget XwFindWidget (w, name)
376 CompositeWidget w;
377 char * name;
380 register int i;
381 register Widget * list;
382 int count;
384 if (strcmp (name, w -> core.name) == 0)
385 return ((Widget) w);
387 list = w -> composite.children;
388 count = w -> composite.num_children;
390 for (i = 0; i < count; i++)
392 if (strcmp (name, (*list) -> core.name) == 0)
393 return (*list);
394 list++;
396 return (NULL);
402 /************************************************************************
404 * Realize
405 * Create the widget window and create the gc's.
407 ************************************************************************/
409 static void Realize (fw, valueMask, attributes)
410 XwFormWidget fw;
411 XtValueMask * valueMask;
412 XSetWindowAttributes * attributes;
415 Mask newValueMask = *valueMask;
416 XtCreateWindow ((Widget)fw, InputOutput, (Visual *) CopyFromParent,
417 newValueMask, attributes);
418 _XwRegisterName(fw);
419 XwProcessRefs (fw, False);
425 /************************************************************************
427 * Resize
429 ************************************************************************/
431 static void Resize (fw)
432 XwFormWidget fw;
435 if (XtIsRealized ((Widget)fw)) XwProcessRefs (fw, False);
442 /************************************************************************
444 * Destroy
445 * Deallocate the head structures of the reference trees.
446 * The rest of the tree has already been deallocated.
448 ************************************************************************/
450 static void Destroy (fw)
451 XwFormWidget fw;
454 XtFree ((char *)(fw -> form.width_tree));
455 XtFree ((char *)(fw -> form.height_tree));
461 /************************************************************************
463 * ConstraintDestroy
464 * Deallocate the allocated referenence names.
466 ************************************************************************/
468 static void ConstraintDestroy (w)
469 XwFormWidget w;
472 XwFormConstraintRec * constraint;
474 constraint = (XwFormConstraintRec *) w -> core.constraints;
476 if (constraint -> x_ref_name != NULL) XtFree (constraint -> x_ref_name);
477 if (constraint -> y_ref_name != NULL) XtFree (constraint -> y_ref_name);
484 /************************************************************************
486 * SetValues
487 * Currently nothing needs to be done. The XtSetValues call
488 * handles geometry requests and form does not define any
489 * new resources.
491 ************************************************************************/
493 static Boolean SetValues (current, request, new)
494 XwFormWidget current, request, new;
497 return (False);
503 /************************************************************************
505 * ConstraintSetValues
506 * Process changes in the constraint set of a widget.
508 ************************************************************************/
510 static Boolean ConstraintSetValues (current, request, new)
511 Widget current, request, new;
514 XwFormConstraintRec * curConstraint;
515 XwFormConstraintRec * newConstraint;
516 XwFormConstraintRec * tempConstraint;
519 curConstraint = (XwFormConstraintRec *) current -> core.constraints;
520 newConstraint = (XwFormConstraintRec *) new -> core.constraints;
523 /* Check the geometrys to see if new's contraint record */
524 /* saved geometry data needs to be updated. */
526 if (XtIsRealized (current))
528 if (new -> core.x != current -> core.x)
529 newConstraint -> set_x = new -> core.x;
530 if (new -> core.y != current -> core.y)
531 newConstraint -> set_y = new -> core.y;
532 if (new -> core.width != current -> core.width)
533 newConstraint -> set_width = new -> core.width;
534 if (new -> core.height != current -> core.height)
535 newConstraint -> set_height = new -> core.height;
539 /* If the reference widget or name has changed, set the */
540 /* opposing member to NULL in order to get the proper */
541 /* referencing. For names, the string space will be */
542 /* deallocated out of current later. */
544 if (newConstraint -> x_ref_widget != curConstraint -> x_ref_widget)
545 newConstraint -> x_ref_name = NULL;
546 else if (newConstraint -> x_ref_name != curConstraint -> x_ref_name)
547 newConstraint -> x_ref_widget = NULL;
549 if (newConstraint -> y_ref_widget != curConstraint -> y_ref_widget)
550 newConstraint -> y_ref_name = NULL;
551 else if (newConstraint -> y_ref_name != curConstraint -> y_ref_name)
552 newConstraint -> y_ref_widget = NULL;
555 /* Get and save copies of the names of the reference widget names */
556 /* and get the reference widgets. */
558 GetRefWidget (&newConstraint -> x_ref_widget,
559 &newConstraint -> x_ref_name, new);
560 GetRefWidget (&newConstraint -> y_ref_widget,
561 &newConstraint -> y_ref_name, new);
564 /* See if the reference widgets have changed. If so, free the */
565 /* old allocated names and set them to the new names. */
567 if (newConstraint -> x_ref_widget != curConstraint -> x_ref_widget)
569 XtFree (curConstraint -> x_ref_name);
570 curConstraint -> x_ref_name = newConstraint -> x_ref_name;
573 if (newConstraint -> y_ref_widget != curConstraint -> y_ref_widget)
575 XtFree (curConstraint -> y_ref_name);
576 curConstraint -> y_ref_name = newConstraint -> y_ref_name;
580 /* See if any constraint data for the widget has changed. */
581 /* Is so, remove the old reference tree elements from the */
582 /* forms constraint processing trees and build and insert */
583 /* new reference tree elements. */
584 /* */
585 /* Once this is finished, reprocess the constraint trees. */
587 if (newConstraint -> x_ref_widget != curConstraint -> x_ref_widget ||
588 newConstraint -> y_ref_widget != curConstraint -> y_ref_widget ||
590 newConstraint -> x_offset != curConstraint -> x_offset ||
591 newConstraint -> y_offset != curConstraint -> y_offset ||
593 newConstraint -> x_vary_offset != curConstraint -> x_vary_offset ||
594 newConstraint -> y_vary_offset != curConstraint -> y_vary_offset ||
596 newConstraint -> x_resizable != curConstraint -> x_resizable ||
597 newConstraint -> y_resizable != curConstraint -> y_resizable ||
599 newConstraint -> x_add_width != curConstraint -> x_add_width ||
600 newConstraint -> y_add_height != curConstraint -> y_add_height ||
602 newConstraint -> x_attach_right != curConstraint -> x_attach_right ||
603 newConstraint -> y_attach_bottom != curConstraint -> y_attach_bottom ||
605 newConstraint -> x_attach_offset != curConstraint -> x_attach_offset ||
606 newConstraint -> y_attach_offset != curConstraint -> y_attach_offset)
608 if (XtIsRealized (current) && current -> core.managed)
610 XwDestroyRefs (current);
612 tempConstraint = (XwFormConstraintRec *) current -> core.constraints;
613 current -> core.constraints = new -> core.constraints;
614 XwMakeRefs (current);
615 current -> core.constraints = (caddr_t) tempConstraint;
618 if (XtIsRealized (current)) XwProcessRefs (new -> core.parent, True);
621 return (False);
627 /************************************************************************
629 * GeometryManager
630 * Always accept the childs new size, set the childs constraint
631 * record size to the new size and process the constraints.
633 ************************************************************************/
635 static XtGeometryResult GeometryManager (w, request, reply)
636 Widget w;
637 XtWidgetGeometry * request;
638 XtWidgetGeometry * reply;
641 XwFormWidget fw = (XwFormWidget) w -> core.parent;
642 XwFormConstraintRec * constraint;
643 XwFormRef * xRef;
644 XwFormRef * yRef;
645 int newBorder = w -> core.border_width;
646 Boolean moveFlag = False;
647 Boolean resizeFlag = False;
650 constraint = (XwFormConstraintRec *) w -> core.constraints;
652 if (request -> request_mode & CWX)
653 constraint -> set_x = request -> x;
655 if (request -> request_mode & CWY)
656 constraint -> set_y = request -> y;
658 if (request -> request_mode & CWWidth)
659 constraint -> set_width = request -> width;
661 if (request -> request_mode & CWHeight)
662 constraint -> set_height = request -> height;
664 if (request -> request_mode & CWBorderWidth)
665 newBorder = request -> border_width;
668 /* If the x or the width has changed, find the horizontal */
669 /* reference tree structure for this widget and update it */
671 xRef = yRef = NULL;
672 if ((request->request_mode & CWWidth) || (request->request_mode & CWX))
674 if ((xRef = XwRefTreeSearch (w, fw -> form.width_tree)) != NULL)
676 if (request->request_mode & CWX)
677 xRef -> set_loc = request -> x;
678 if (request->request_mode & CWWidth)
679 xRef -> set_size = request -> width;
684 /* If the y or the height has changed, find the vertical */
685 /* reference tree structure for this widget and update it */
687 if ((request->request_mode & CWHeight) || (request->request_mode & CWY))
689 if ((yRef = XwRefTreeSearch (w, fw -> form.height_tree)) != NULL)
691 if (request->request_mode & CWY)
692 yRef -> set_loc = request -> y;
693 if (request->request_mode & CWHeight)
694 yRef -> set_size = request -> height;
699 /* Process the constraints if either of the ref structs have changed */
701 if (xRef != NULL || yRef != NULL)
703 if ((request->request_mode & CWX) || (request->request_mode & CWY))
704 moveFlag = True;
705 if ((request->request_mode & CWWidth) ||
706 (request->request_mode & CWHeight))
707 resizeFlag = True;
709 if (moveFlag && resizeFlag)
710 XtConfigureWidget (w, constraint -> set_x, constraint -> set_y,
711 constraint -> set_width, constraint -> set_height,
712 newBorder);
713 else if (resizeFlag)
714 XtResizeWidget (w, constraint -> set_width, constraint -> set_height,
715 newBorder);
716 else if (moveFlag)
717 XtMoveWidget (w, constraint -> set_x, constraint -> set_y);
720 XwProcessRefs (w -> core.parent, True);
724 /* See if an almost condition should be returned */
726 if (((request->request_mode & CWX) && w->core.x != request->x) ||
727 ((request->request_mode & CWY) && w->core.y != request->y) ||
728 ((request->request_mode & CWWidth) &&
729 w->core.width != request->width) ||
730 ((request->request_mode & CWHeight) &&
731 w->core.height != request->height))
733 reply->request_mode = request->request_mode;
735 if (request->request_mode & CWX) reply->x = w->core.x;
736 if (request->request_mode & CWY) reply->y = w->core.y;
737 if (request->request_mode & CWWidth) reply->width = w->core.width;
738 if (request->request_mode & CWHeight) reply->height = w->core.height;
739 if (request->request_mode & CWBorderWidth)
740 reply->border_width = request->border_width;
741 if (request->request_mode & CWSibling)
742 reply->sibling = request->sibling;
743 if (request->request_mode & CWStackMode)
744 reply->stack_mode = request->stack_mode;
746 return (XtGeometryAlmost);
749 return (XtGeometryDone);
755 /************************************************************************
757 * ChangeManaged
759 ************************************************************************/
761 static void ChangeManaged (fw)
762 XwFormWidget fw;
765 Widget child;
766 XwFormConstraintRec * constraint;
767 register int i;
770 /* If the widget is being managed, build up the reference */
771 /* structures for it, adjust any references, and process the */
772 /* reference set. If unmanaged, remove its reference. */
774 for (i = 0; i < fw -> composite.num_children; i++)
776 child = fw -> composite.children[i];
777 constraint = (XwFormConstraintRec *) child -> core.constraints;
779 if (constraint -> set_width == 0)
781 constraint -> set_x = child -> core.x;
782 constraint -> set_y = child -> core.y;
783 constraint -> set_width = child -> core.width;
784 constraint -> set_height = child -> core.height;
787 if (child -> core.managed != constraint -> managed)
789 if (child -> core.managed)
791 if (constraint->width_when_unmanaged != child->core.width)
792 constraint->set_width = child->core.width;
793 if (constraint->height_when_unmanaged != child->core.height)
794 constraint->set_height = child->core.height;
795 XwMakeRefs (child);
797 else
799 constraint -> width_when_unmanaged = child->core.width;
800 constraint -> height_when_unmanaged = child->core.height;
801 XwDestroyRefs (child);
803 constraint -> managed = child -> core.managed;
807 XwProcessRefs (fw, True);
813 /************************************************************************
815 * XwMakeRefs
816 * Build up and insert into the forms reference trees the reference
817 * structures needed for the widget w.
819 ************************************************************************/
821 static void XwMakeRefs (w)
822 Widget w;
825 Widget xRefWidget;
826 Widget yRefWidget;
827 XwFormWidget formWidget;
828 XwFormConstraintRec * constraint;
829 XwFormRef * xRefParent;
830 XwFormRef * yRefParent;
831 XwFormRef * xRef;
832 XwFormRef * yRef;
833 XwFormRef * checkRef;
834 register int i;
837 formWidget = (XwFormWidget) w -> core.parent;
838 constraint = (XwFormConstraintRec *) w -> core.constraints;
841 /* The "true" reference widget may be unmanaged, so */
842 /* we need to back up through the reference set */
843 /* perhaps all the way to Form. */
845 xRefWidget = XwFindValidRef (constraint -> x_ref_widget, XwHORIZONTAL,
846 formWidget -> form.width_tree);
847 yRefWidget = XwFindValidRef (constraint -> y_ref_widget, XwVERTICAL,
848 formWidget -> form.height_tree);
851 /* Search the referencing trees for the referencing widgets */
852 /* The constraint reference struct will be added as a child */
853 /* of this struct. */
855 if (xRefWidget != NULL)
856 xRefParent = XwRefTreeSearch (xRefWidget, formWidget -> form.width_tree);
858 if (yRefWidget != NULL)
859 yRefParent = XwRefTreeSearch (yRefWidget, formWidget->form.height_tree);
862 /* Allocate, initialize, and insert the reference structures */
864 if (xRefWidget != NULL)
866 xRef = XwGetFormRef (w, xRefWidget, constraint->x_offset,
867 constraint->x_add_width, constraint->x_vary_offset,
868 constraint->x_resizable, constraint->x_attach_right,
869 constraint->x_attach_offset,
870 constraint->set_x, constraint->set_width);
871 XwAddRef (xRefParent, xRef);
874 if (yRefWidget != NULL)
876 yRef = XwGetFormRef(w, yRefWidget, constraint->y_offset,
877 constraint->y_add_height, constraint->y_vary_offset,
878 constraint->y_resizable, constraint->y_attach_bottom,
879 constraint->y_attach_offset,
880 constraint->set_y, constraint->set_height);
881 XwAddRef (yRefParent, yRef);
885 /* Search through the parents reference set to get any child */
886 /* references which need to be made child references of the */
887 /* widget just added. */
889 for (i = 0; i < xRefParent -> ref_to_count; i++)
891 checkRef = xRefParent -> ref_to[i];
892 constraint = (XwFormConstraintRec *) checkRef->this->core.constraints;
894 if (XwFindValidRef (constraint->x_ref_widget, XwHORIZONTAL,
895 formWidget -> form.width_tree) != xRefWidget)
897 XwRemoveRef (xRefParent, checkRef);
898 checkRef -> ref = xRef -> this;
899 XwAddRef (xRef, checkRef);
903 for (i = 0; i < yRefParent -> ref_to_count; i++)
905 checkRef = yRefParent -> ref_to[i];
906 constraint = (XwFormConstraintRec *) checkRef->this->core.constraints;
908 if (XwFindValidRef (constraint->y_ref_widget, XwVERTICAL,
909 formWidget -> form.height_tree) != yRefWidget)
911 XwRemoveRef (yRefParent, checkRef);
912 checkRef -> ref = yRef -> this;
913 XwAddRef (yRef, checkRef);
921 /************************************************************************
923 * XwDestroyRefs
924 * Remove and deallocate the reference structures for the widget w.
926 ************************************************************************/
928 static void XwDestroyRefs (w)
929 Widget w;
932 Widget xRefWidget;
933 Widget yRefWidget;
934 XwFormWidget formWidget;
935 XwFormConstraintRec * constraint;
936 XwFormRef * xRefParent;
937 XwFormRef * yRefParent;
938 XwFormRef * xRef;
939 XwFormRef * yRef;
940 XwFormRef * tempRef;
941 register int i;
944 formWidget = (XwFormWidget) w -> core.parent;
945 constraint = (XwFormConstraintRec *) w -> core.constraints;
948 /* Search through the reference trees to see if the widget */
949 /* is within the tree. */
951 xRefWidget = w;
952 yRefWidget = w;
954 xRefParent =
955 XwParentRefTreeSearch (xRefWidget, formWidget -> form.width_tree,
956 formWidget -> form.width_tree);
957 yRefParent =
958 XwParentRefTreeSearch (yRefWidget, formWidget -> form.height_tree,
959 formWidget -> form.height_tree);
962 /* For both the width and height references, if the ref parent was */
963 /* not null, find the reference to be removed within the parents */
964 /* list, remove this reference. Then, for any references attached */
965 /* to the one just removed, reparent them to the parent reference. */
967 if (xRefParent != NULL)
969 for (i = 0; i < xRefParent -> ref_to_count; i++)
971 if (xRefParent -> ref_to[i] -> this == xRefWidget)
973 xRef = xRefParent -> ref_to[i];
974 break;
978 XwRemoveRef (xRefParent, xRefParent -> ref_to[i]);
980 while (xRef -> ref_to_count)
982 tempRef = xRef -> ref_to[0];
983 tempRef -> ref = xRefParent -> this;
984 XwRemoveRef (xRef, tempRef);
985 XwAddRef (xRefParent, tempRef);
988 XtFree ((char *)xRef);
991 if (yRefParent != NULL)
993 for (i = 0; i < yRefParent -> ref_to_count; i++)
995 if (yRefParent -> ref_to[i] -> this == yRefWidget)
997 yRef = yRefParent -> ref_to[i];
998 break;
1002 XwRemoveRef (yRefParent, yRef);
1004 while (yRef -> ref_to_count)
1006 tempRef = yRef -> ref_to[0];
1007 tempRef -> ref = yRefParent -> this;
1008 XwRemoveRef (yRef, tempRef);
1009 XwAddRef (yRefParent, tempRef);
1012 XtFree ((char *)yRef);
1019 /************************************************************************
1021 * XwGetFormRef
1022 * Allocate and initialize a form constraint referencing structure.
1024 ************************************************************************/
1026 static XwFormRef *
1027 XwGetFormRef (this, ref, offset, add, vary,
1028 resizable, attach, attach_offset, loc, size)
1029 Widget this;
1030 Widget ref;
1031 int offset;
1032 Boolean add;
1033 Boolean vary;
1034 Boolean resizable;
1035 Boolean attach;
1036 int attach_offset;
1039 XwFormRef * formRef;
1041 formRef = (XwFormRef *) XtMalloc (sizeof (XwFormRef));
1042 formRef -> this = this;
1043 formRef -> ref = ref;
1044 formRef -> offset = offset;
1045 formRef -> add = add;
1046 formRef -> vary = vary;
1047 formRef -> resizable = resizable;
1048 formRef -> attach = attach;
1049 formRef -> attach_offset = attach_offset;
1051 formRef -> set_loc = loc;
1052 formRef -> set_size = size;
1054 formRef -> ref_to = NULL;
1055 formRef -> ref_to_count = 0;
1057 return (formRef);
1063 /************************************************************************
1065 * XwFindValidRef
1066 * Given an initial reference widget to be used as a constraint,
1067 * find a valid (managed) reference widget. This is done by
1068 * backtracking through the widget references listed in the
1069 * constraint records. If no valid constraint is found, "form"
1070 * is returned indicating that this reference should be stuck
1071 * immediately under the form reference structure.
1073 ************************************************************************/
1075 static Widget XwFindValidRef (refWidget, refType, formRef)
1076 Widget refWidget;
1077 int refType;
1078 XwFormRef * formRef;
1081 XwFormConstraintRec * constraint;
1083 if (refWidget == NULL) return (NULL);
1085 while (1)
1087 if (XwRefTreeSearch (refWidget, formRef) != NULL) return (refWidget);
1089 constraint = (XwFormConstraintRec *) refWidget -> core.constraints;
1091 if (refType == XwHORIZONTAL) refWidget = constraint -> x_ref_widget;
1092 else refWidget = constraint -> y_ref_widget;
1094 if (refWidget == NULL) return (refWidget -> core.parent);
1101 /************************************************************************
1103 * XwRefTreeSearch
1104 * Search the reference tree until the widget listed is found.
1106 ************************************************************************/
1108 static XwFormRef * XwRefTreeSearch (w, formRef)
1109 Widget w;
1110 XwFormRef * formRef;
1113 register int i;
1114 XwFormRef * tempRef;
1116 if (formRef == NULL) return (NULL);
1117 if (formRef -> this == w) return (formRef);
1119 for (i = 0; i < formRef -> ref_to_count; i++)
1121 tempRef = XwRefTreeSearch (w, formRef -> ref_to[i]);
1122 if (tempRef != NULL) return (tempRef);
1125 return (NULL);
1131 /************************************************************************
1133 * XwParentRefTreeSearch
1134 * Search the reference tree until the parent reference of the
1135 * widget listed is found.
1137 ************************************************************************/
1139 static XwFormRef * XwParentRefTreeSearch (w, wFormRef, parentFormRef)
1140 Widget w;
1141 XwFormRef * wFormRef;
1142 XwFormRef * parentFormRef;
1145 register int i;
1146 XwFormRef * tempRef;
1148 if (parentFormRef == NULL) return (NULL);
1149 if (wFormRef -> this == w) return (parentFormRef);
1151 for (i = 0; i < wFormRef -> ref_to_count; i++)
1153 tempRef =
1154 XwParentRefTreeSearch (w, wFormRef -> ref_to[i], wFormRef);
1155 if (tempRef != NULL) return (tempRef);
1158 return (NULL);
1164 /************************************************************************
1166 * XwAddRef
1167 * Add a reference structure into a parent reference structure.
1169 ************************************************************************/
1171 static void XwAddRef (refParent, ref)
1172 XwFormRef * refParent;
1173 XwFormRef * ref;
1176 refParent -> ref_to =
1177 (XwFormRef **)
1178 XtRealloc ((char *) refParent -> ref_to,
1179 sizeof (XwFormRef *) * (refParent -> ref_to_count + 1));
1181 refParent -> ref_to[refParent -> ref_to_count] = ref;
1182 refParent -> ref_to_count += 1;
1188 /************************************************************************
1190 * XwRemoveRef
1191 * Remove a reference structure from a parent reference structure.
1193 ************************************************************************/
1195 static void XwRemoveRef (refParent, ref)
1196 XwFormRef * refParent;
1197 XwFormRef * ref;
1200 register int i, j;
1202 for (i = 0; i < refParent -> ref_to_count; i++)
1204 if (refParent -> ref_to[i] == ref)
1206 for (j = i; j < refParent -> ref_to_count - 1; j++)
1207 refParent -> ref_to[j] = refParent -> ref_to[j + 1];
1208 break;
1212 if (refParent -> ref_to_count > 1)
1214 refParent -> ref_to =
1215 (XwFormRef **) XtRealloc ((char *) refParent -> ref_to,
1216 sizeof (XwFormRef *) * (refParent -> ref_to_count - 1));
1219 else
1221 XtFree ((char *)(refParent -> ref_to));
1222 refParent -> ref_to = NULL;
1225 refParent -> ref_to_count -= 1;
1231 /************************************************************************
1233 * XwProcessRefs
1234 * Traverse throught the form's reference trees, calculate new
1235 * child sizes and locations based on the constraints and adjust
1236 * the children as is calculated. The resizable flag indicates
1237 * whether the form can be resized or not.
1239 ************************************************************************/
1241 static void XwProcessRefs (fw, formResizable)
1242 XwFormWidget fw;
1243 Boolean formResizable;
1246 int formWidth, formHeight;
1247 register int i, j;
1249 int horDepth, horLeaves;
1250 int vertDepth, vertLeaves;
1251 XwFormProcess ** horProcessList;
1252 XwFormProcess ** vertProcessList;
1254 XtGeometryResult geometryReturn;
1255 Dimension replyW, replyH;
1257 XwFormConstraintRec * constraintRec;
1258 Widget child;
1259 Boolean moveFlag, resizeFlag;
1262 /* Initialize the form width and height variables */
1264 if (fw -> manager.layout == XwIGNORE) formResizable = False;
1266 if (formResizable) formWidth = formHeight = -1;
1267 else
1269 formWidth = fw -> core.width;
1270 formHeight = fw -> core.height;
1274 /* Traverse the reference trees to find the depth and leaf node count */
1276 leaves = 0;
1277 depth = 0;
1278 XwFindDepthAndCount (fw -> form.width_tree, 1);
1279 horDepth = depth;
1280 horLeaves = leaves;
1282 leaves = 0;
1283 depth = 0;
1284 XwFindDepthAndCount (fw -> form.height_tree, 1);
1285 vertDepth = depth;
1286 vertLeaves = leaves;
1288 if (horDepth == 0 && vertDepth == 0)
1289 return;
1292 /* Allocate and initialize the constraint array processing structures */
1294 horProcessList =
1295 (XwFormProcess **) XtMalloc (sizeof (XwFormProcess **) * horLeaves);
1296 for (i = 0; i < horLeaves; i++)
1298 horProcessList[i] =
1299 (XwFormProcess *) XtMalloc (sizeof (XwFormProcess) * horDepth);
1301 for (j = 0; j < horDepth; j++)
1302 horProcessList[i][j].ref = NULL;
1306 vertProcessList =
1307 (XwFormProcess **) XtMalloc (sizeof (XwFormProcess **) * vertLeaves);
1308 for (i = 0; i < vertLeaves; i++)
1310 vertProcessList[i] =
1311 (XwFormProcess *) XtMalloc (sizeof (XwFormProcess) * vertDepth);
1313 for (j = 0; j < vertDepth; j++)
1314 vertProcessList[i][j].ref = NULL;
1318 /* Initialize the process array placing each node of the tree into */
1319 /* the array such that it is listed only once and its first children */
1320 /* listed directly next within the array. */
1322 arrayIndex = 0;
1323 XwInitProcessList (horProcessList, fw -> form.width_tree, 0);
1324 arrayIndex = 0;
1325 XwInitProcessList (vertProcessList, fw -> form.height_tree, 0);
1328 /* Process each array such that each row of the arrays contain */
1329 /* their required sizes and locations to match the constraints */
1331 XwConstrainList (horProcessList, horLeaves,
1332 horDepth, &formWidth, formResizable, XwHORIZONTAL);
1333 XwConstrainList (vertProcessList, vertLeaves,
1334 vertDepth, &formHeight, formResizable, XwVERTICAL);
1337 /* If the form is resizable and the form width or height returned */
1338 /* is different from the current form width or height, then make */
1339 /* a geometry request to get the new form size. If almost is */
1340 /* returned, use these sizes and reprocess the constrain lists */
1342 if (formResizable &&
1343 (formWidth != fw -> core.width || formHeight != fw -> core.height))
1345 geometryReturn =
1346 XtMakeResizeRequest((Widget)fw, formWidth, formHeight, &replyW, &replyH);
1348 if (geometryReturn == XtGeometryAlmost)
1350 formWidth = replyW;
1351 formHeight = replyH;
1353 XtMakeResizeRequest((Widget)fw, formWidth, formHeight, NULL, NULL);
1355 XwConstrainList (horProcessList, horLeaves,
1356 horDepth, &formWidth, False, XwHORIZONTAL);
1357 XwConstrainList (vertProcessList, vertLeaves,
1358 vertDepth, &formHeight, False, XwVERTICAL);
1361 else if (geometryReturn == XtGeometryNo)
1363 formWidth = fw -> core.width;
1364 formHeight = fw -> core.height;
1366 XwConstrainList (horProcessList, horLeaves,
1367 horDepth, &formWidth, False, XwHORIZONTAL);
1368 XwConstrainList (vertProcessList, vertLeaves,
1369 vertDepth, &formHeight, False, XwVERTICAL);
1374 /* Process the forms child list to compare the widget sizes and */
1375 /* locations with the widgets current values and if changed, */
1376 /* reposition, resize, or reconfigure the child. */
1378 for (i = 0; i < fw -> composite.num_children; i++)
1380 child = (Widget) fw -> composite.children[i];
1382 if (child -> core.managed)
1384 constraintRec = (XwFormConstraintRec *) child -> core.constraints;
1386 moveFlag = resizeFlag = False;
1388 if (constraintRec -> x != child -> core.x ||
1389 constraintRec -> y != child -> core.y)
1390 moveFlag = True;
1392 if (constraintRec -> width != child -> core.width ||
1393 constraintRec -> height != child -> core.height)
1394 resizeFlag = True;
1396 if (moveFlag && resizeFlag)
1397 XtConfigureWidget (child, constraintRec->x, constraintRec->y,
1398 constraintRec->width, constraintRec->height,
1399 child -> core.border_width);
1400 else if (moveFlag)
1401 XtMoveWidget (child, constraintRec->x, constraintRec->y);
1402 else if (resizeFlag)
1403 XtResizeWidget (child, constraintRec->width,
1404 constraintRec->height, child->core.border_width);
1408 XwFreeConstraintList (horProcessList, horLeaves);
1409 XwFreeConstraintList (vertProcessList, vertLeaves);
1415 /************************************************************************
1417 * XwFreeConstraintList
1418 * Free an allocated constraint list.
1420 ************************************************************************/
1422 static void XwFreeConstraintList (processList, leaves)
1423 XwFormProcess ** processList;
1424 int leaves;
1427 register int i;
1430 /* Free each array attached to the list then free the list */
1432 for (i = 0; i < leaves; i++)
1433 XtFree ((char *)(processList[i]));
1435 XtFree ((char *)processList);
1441 /************************************************************************
1443 * XwFindDepthAndCount
1444 * Search a constraint reference tree and find the maximum depth
1445 * of the tree and the number of leaves in the tree.
1447 ************************************************************************/
1449 static void XwFindDepthAndCount (node, nodeLevel)
1450 XwFormRef * node;
1451 int nodeLevel;
1454 register int i;
1456 if (node -> ref_to == NULL) leaves++;
1457 else
1459 nodeLevel++;
1460 if (nodeLevel > depth) depth = nodeLevel;
1461 for (i = 0; i < node -> ref_to_count; i++)
1462 XwFindDepthAndCount (node -> ref_to[i], nodeLevel);
1469 /************************************************************************
1471 * XwInitProcessList
1472 * Search a constraint reference tree and find place the ref node
1473 * pointers into the list.
1475 ************************************************************************/
1477 static void XwInitProcessList (processList, node, nodeLevel)
1478 XwFormProcess ** processList;
1479 XwFormRef * node;
1480 int nodeLevel;
1483 register int i;
1485 processList[arrayIndex][nodeLevel].ref = node;
1487 if (node -> ref_to == NULL)
1489 processList[arrayIndex][nodeLevel].leaf = True;
1490 arrayIndex++;
1492 else
1494 processList[arrayIndex][nodeLevel].leaf = False;
1495 nodeLevel++;
1496 for (i = 0; i < node -> ref_to_count; i++)
1497 XwInitProcessList (processList, node -> ref_to[i], nodeLevel);
1503 /************************************************************************
1505 * XwConstrainList
1506 * Process each array such that each row of the arrays contain
1507 * their required sizes and locations to match the constraints
1509 ************************************************************************/
1511 static void XwConstrainList (processList, leaves, depth,
1512 formSize, varySize, orient)
1513 XwFormProcess ** processList;
1514 int leaves;
1515 int depth;
1516 int * formSize;
1517 Boolean varySize;
1518 int orient;
1521 register int i, j;
1522 register XwFormRef * ref;
1523 XwFormConstraintRec * constraint;
1524 XwFormConstraintRec * parentConstraint;
1525 int heldSize;
1526 int sizeDif;
1527 int vary, resize;
1528 int varyCount, varyAmount;
1529 int resizeCount, resizeAmount;
1530 int constantSubtract;
1531 int addAmount, subtractAmount;
1532 int size, separation;
1536 heldSize = 0;
1539 for (i = 0; i < leaves; i++) /* Process all array lines */
1541 processList[i][0].size = 0;
1542 processList[i][0].loc = 0;
1545 for (j = 1; j < depth; j++) /* Process array line */
1547 ref = processList[i][j].ref;
1549 if (ref != NULL)
1551 processList[i][j].size = ref -> set_size;
1553 if (ref -> ref == ref -> this -> core.parent)
1555 if (ref -> offset != 0)
1556 processList[i][j].loc = ref -> offset;
1557 else
1558 processList[i][j].loc = ref -> set_loc;
1560 else
1562 processList[i][j].loc =
1563 processList[i][j - 1].loc + ref->offset;
1564 if (ref -> add)
1565 processList[i][j].loc += processList[i][j - 1].size +
1566 processList[i][j].ref -> this -> core.border_width * 2;
1570 else
1572 processList[i][j].ref = processList[i - 1][j].ref;
1573 processList[i][j].loc = processList[i - 1][j].loc;
1574 processList[i][j].size = processList[i - 1][j].size;
1575 processList[i][j].leaf = processList[i - 1][j].leaf;
1578 if (processList[i][j].leaf)
1580 if (processList[i][0].size < processList[i][j].size +
1581 processList[i][j].ref -> this -> core.border_width * 2 +
1582 processList[i][j].loc + ref -> attach_offset)
1584 processList[i][0].size = processList[i][j].size +
1585 processList[i][j].ref -> this -> core.border_width * 2 +
1586 processList[i][j].loc + ref -> attach_offset;
1589 if (processList[i][j].leaf && processList[i][0].size > heldSize)
1590 heldSize = processList[i][0].size;
1592 break;
1598 /* Each array line has now been processed to optimal size. Reprocess */
1599 /* each line to constrain it to formSize if not varySize or to */
1600 /* heldSize if varySize. */
1602 if (varySize)
1603 *formSize = heldSize;
1607 for (i = 0; i < leaves; i++)
1610 /* For each array line if the 0th size (calculated form size needed */
1611 /* for this array line is less than the form size then increase the */
1612 /* seperations between widgets whose constaints allow it. */
1613 /* If can't do it by varying separation, but can do it by resizing, */
1614 /* then do that. */
1616 if (processList[i][0].size < *formSize)
1618 sizeDif = *formSize - processList[i][0].size;
1620 varyCount = 0;
1621 resizeCount = 0;
1622 for (j = 1; j < depth; j++)
1624 /* Can't vary the first spacing */
1625 if (j > 1 && processList[i][j].ref -> vary) varyCount++;
1626 if (processList[i][j].ref -> resizable) resizeCount++;
1627 if (processList[i][j].leaf) break;
1630 addAmount = 0;
1631 resizeAmount = 0;
1632 if (varyCount == 0)
1634 varyAmount = 0;
1635 if (resizeCount != 0)
1636 resizeAmount = sizeDif / resizeCount;
1638 else varyAmount = sizeDif / varyCount;
1640 j = 1;
1642 while (j < depth)
1644 if (j > 1 && processList[i][j].ref -> vary)
1645 addAmount += varyAmount;
1646 processList[i][j].loc += addAmount;
1647 if (processList[i][j].ref -> resizable)
1649 processList[i][j].size += resizeAmount;
1650 addAmount += resizeAmount;
1653 if (processList[i][j].leaf) break;
1655 j++;
1658 if (j > 1)
1660 if (processList[i][j].ref -> vary &&
1661 processList[i][j].ref -> attach)
1662 processList[i][j].loc = *formSize - processList[i][j].size -
1663 processList[i][j].ref -> attach_offset;
1664 else if (processList[i][j].ref -> vary == False &&
1665 processList[i][j].ref -> resizable &&
1666 processList[i][j].ref -> attach)
1668 processList[i][j].size =
1669 *formSize - processList[i][j].loc -
1670 processList[i][j].ref -> this -> core.border_width * 2 -
1671 processList[i][j].ref -> attach_offset;
1674 else
1676 if (processList[i][j].ref -> vary == False &&
1677 processList[i][j].ref -> resizable &&
1678 processList[i][j].ref -> attach)
1680 processList[i][j].loc = processList[i][j].ref -> offset;
1681 processList[i][j].size =
1682 *formSize - processList[i][j].loc -
1683 processList[i][j].ref -> this -> core.border_width * 2 -
1684 processList[i][j].ref -> attach_offset;
1687 else if (processList[i][j].ref -> vary &&
1688 processList[i][j].ref -> attach)
1690 processList[i][j].loc =
1691 *formSize - processList[i][j].size -
1692 processList[i][j].ref -> this -> core.border_width * 2 -
1693 processList[i][j].ref -> attach_offset;
1695 else if (processList[i][j].ref -> vary &&
1696 processList[i][j].ref -> attach == False)
1698 processList[i][j].loc = processList[i][j].ref -> offset;
1704 /* If the form size has gotton smaller, process the vary constraints */
1705 /* until the needed size is correct or all seperations are 1 pixel. */
1706 /* If separations go to 1, then process the resizable widgets */
1707 /* until the needed size is correct or the sizes have gone to 1 */
1708 /* pixel. If the size is still not correct punt, cannot find a */
1709 /* usable size so clip it. */
1711 if (processList[i][0].size > *formSize)
1713 sizeDif = processList[i][0].size - *formSize;
1715 varyAmount = 0;
1716 varyCount = 0;
1718 j = 0;
1721 j++;
1723 if (j > 1 && processList[i][j].ref -> vary &&
1724 processList[i][j].ref -> offset)
1726 varyAmount += processList[i][j].ref -> offset;
1727 varyCount++;
1730 while (processList[i][j].leaf == False);
1733 resizeAmount = 0;
1734 resizeCount = 0;
1735 for (j = 1; j < depth; j++)
1737 if (processList[i][j].ref->resizable && processList[i][j].size > 1)
1739 if (processList[i][j].leaf || processList[i][j+1].ref->add)
1741 resizeCount++;
1742 resizeAmount += processList[i][j].size - 1;
1745 if (processList[i][j].leaf) break;
1749 /* Do we have enough varience to match the constraints? */
1751 if (varyAmount + resizeAmount > sizeDif)
1754 /* first process out the vary amount */
1756 if (varyCount)
1760 subtractAmount = 0;
1762 for (j = 1; j < depth; j++)
1764 if (j > 1 && processList[i][j].ref -> vary)
1766 vary =
1767 processList[i][j].loc - processList[i][j - 1].loc;
1769 if (processList[i][j].ref -> add)
1770 vary = vary - processList[i][j - 1].size - 1 -
1771 processList[i][j-1].ref->
1772 this->core.border_width * 2;
1774 else vary = 0;
1776 if (vary > 0) subtractAmount++;
1778 if (subtractAmount)
1780 processList[i][j].loc -= subtractAmount;
1781 sizeDif--;
1784 if (processList[i][j].leaf) break;
1787 while (subtractAmount != 0 && sizeDif > 0);
1791 /* now process resize constraints if further constraint */
1792 /* processing is necessary. */
1794 if (sizeDif)
1796 if (resizeAmount > sizeDif) resizeAmount = sizeDif;
1797 if (resizeCount) constantSubtract = resizeAmount / resizeCount;
1799 while (resizeAmount > 0)
1801 subtractAmount = 0;
1803 for (j = 1; j < depth; j++)
1805 if (processList[i][j].ref -> add)
1806 processList[i][j].loc -= subtractAmount;
1808 if (processList[i][j].ref -> resizable)
1810 if (processList[i][j].leaf ||
1811 processList[i][j + 1].ref -> add)
1812 resize = processList[i][j].size - 1;
1813 else
1814 resize = 0;
1816 if (resize > 1)
1818 if (constantSubtract < resize)
1819 resize = constantSubtract;
1820 subtractAmount += resize;
1821 processList[i][j].size -= resize;
1825 if (processList[i][j].leaf) break;
1828 resizeAmount -= subtractAmount;
1829 constantSubtract = 1;
1838 /* Now each array line is processed such that its line is properly */
1839 /* constrained to match the specified form size. Since a single */
1840 /* widget reference structure can be referenced in multiple array */
1841 /* lines, the minumum constraint for each widget needs to be found. */
1842 /* When found, the width and height will be placed into the widgets */
1843 /* constraint structure. */
1845 for (i = 1; i < depth; i++)
1847 ref = NULL;
1849 for (j = 0; j < leaves + 1; j++) /* loop one to many - for exit */
1851 if (j == leaves || ref != processList[j][i].ref)
1853 if (j == leaves || ref != NULL)
1855 if (ref != NULL)
1857 constraint =
1858 (XwFormConstraintRec *) ref -> this -> core.constraints;
1859 parentConstraint =
1860 (XwFormConstraintRec *) ref -> ref -> core.constraints;
1862 if (orient == XwHORIZONTAL) constraint -> width = size;
1863 else constraint -> height = size;
1865 if (i > 1)
1867 if (orient== XwHORIZONTAL)
1868 constraint -> x = parentConstraint -> x + separation;
1869 else
1870 constraint -> y = parentConstraint -> y + separation;
1872 else
1874 if (orient == XwHORIZONTAL) constraint -> x = separation;
1875 else constraint -> y = separation;
1879 if (j == leaves) break; /* exit out of the inner loop */
1882 ref = processList[j][i].ref;
1883 separation = 10000000;
1884 size = 10000000;
1887 if (ref != NULL)
1889 if (size > processList[j][i].size) size = processList[j][i].size;
1891 if (i > 1)
1893 if (separation > processList[j][i].loc-processList[j][i-1].loc)
1894 separation = processList[j][i].loc-processList[j][i-1].loc;
1896 else
1897 if (separation > processList[j][i].loc)
1898 separation = processList[j][i].loc;