home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume10 / xt-examples / part04 / Box.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-04  |  8.4 KB  |  289 lines

  1. /***********************************************************
  2. Copyright 1990 by Digital Equipment Corporation, Maynard, Massachusetts.
  3.  
  4.                         All Rights Reserved
  5.  
  6. Permission to use, copy, modify, and distribute these examples for any
  7. purpose and without fee is hereby granted, provided that the above
  8. copyright notice appear in all copies and that both that copyright
  9. notice and this permission notice appear in supporting documentation,
  10. and that the name of Digital not be used in advertising or publicity
  11. pertaining to distribution of the software without specific, written
  12. prior permission.
  13.  
  14. DIGITAL AND THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
  15. SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  16. FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT
  17. OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  18. OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  19. OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  20. OR PERFORMANCE OF THIS SOFTWARE.
  21.  
  22. ******************************************************************/
  23.  
  24. #include <X11/IntrinsicP.h>    /* Intrinsics header file */
  25. #include <X11/StringDefs.h>    /* Resource string definitions */
  26. #include "BoxP.h"        /* Box private header file */
  27. #include "LabelGadge.h"        /* To check LabelGadgets */
  28.  
  29. #define Offset(field) XtOffsetOf(BoxRec, box.field)
  30.  
  31. static XtResource resources[] = {
  32.     {XtNmargin, XtCMargin, XtRDimension, sizeof(Dimension),
  33.     Offset(margin), XtRImmediate, (XtPointer) 10},
  34. };
  35.  
  36. #undef Offset
  37.  
  38. /* Forward declarations */
  39.  
  40. static void ChangeManaged(), Initialize(), InsertChild(),
  41.     DeleteChild(), Redisplay();
  42. static XtGeometryResult GeometryManager();
  43. static Boolean SetValues(), AcceptFocus();
  44.  
  45. static CompositeClassExtensionRec compositeExtension = {
  46.     /* next_extension        */ NULL,
  47.     /* record_type        */ NULLQUARK,
  48.     /* version            */ XtCompositeExtensionVersion,
  49.     /* record_size        */ sizeof(CompositeClassExtensionRec),
  50.     /* accepts_objects        */ TRUE
  51. };
  52.  
  53. BoxClassRec boxClassRec = {
  54.     /* Core class part */
  55.   {
  56.     /* superclass         */    (WidgetClass) &compositeClassRec,
  57.     /* class_name         */ "Box",
  58.     /* widget_size         */ sizeof(BoxRec),
  59.     /* class_initialize      */ NULL,
  60.     /* class_part_initialize */ NULL,
  61.     /* class_inited          */    FALSE,
  62.     /* initialize         */    Initialize,
  63.     /* initialize_hook       */    NULL,
  64.     /* realize             */    XtInheritRealize,
  65.     /* actions             */    NULL,
  66.     /* num_actions         */    0,
  67.     /* resources         */    resources,
  68.     /* num_resources         */    XtNumber(resources),
  69.     /* xrm_class         */    NULLQUARK,
  70.     /* compress_motion         */    TRUE,
  71.     /* compress_exposure     */    XtExposeCompressMultiple,
  72.     /* compress_enterleave   */    TRUE,
  73.     /* visible_interest         */    FALSE,
  74.     /* destroy             */    NULL,
  75.     /* resize             */    NULL,
  76.     /* expose             */    Redisplay,
  77.     /* set_values         */    SetValues,
  78.     /* set_values_hook       */    NULL,            
  79.     /* set_values_almost     */    XtInheritSetValuesAlmost,  
  80.     /* get_values_hook       */    NULL,            
  81.     /* accept_focus         */    AcceptFocus,
  82.     /* version             */    XtVersion,
  83.     /* callback offsets      */    NULL,
  84.     /* tm_table              */    NULL,
  85.     /* query_geometry         */    XtInheritQueryGeometry,
  86.     /* display_accelerator   */    NULL,
  87.     /* extension         */    NULL,
  88.   },
  89.    /* Composite class part */
  90.   {
  91.     /* geometry_manager         */    GeometryManager,
  92.     /* change_managed         */    ChangeManaged,
  93.     /* insert_child         */    InsertChild,
  94.     /* delete_child         */    DeleteChild,
  95.     /* extension         */    (XtPointer) &compositeExtension,
  96.   },
  97.    /* Box class part */
  98.   {
  99.     /* extension         */    NULL,
  100.   }
  101. };
  102.  
  103. WidgetClass boxWidgetClass = (WidgetClass) &boxClassRec;
  104.  
  105. static void DeleteChild(w)
  106.     Widget w;
  107. {
  108.     BoxWidget box = (BoxWidget) XtParent(w);
  109.  
  110.     if (box->box.last_focus == w) box->box.last_focus = NULL;
  111.  
  112.     (*((CompositeWidgetClass)(boxWidgetClass->core_class.superclass))->
  113.         composite_class.delete_child) (w);
  114. }
  115.  
  116. static void InsertChild(w)
  117.     Widget w;
  118. {
  119.     String params[2];
  120.     Cardinal num_params;
  121.     Widget parent = XtParent(w);
  122.  
  123.     if (!XtIsWidget(w) && !XtIsSubclass(w, labelGadgetClass)) {
  124.     params[0] = XtClass(w)->core_class.class_name;
  125.     params[1] = XtClass(parent)->core_class.class_name;
  126.     num_params = 2;
  127.     XtAppErrorMsg(XtWidgetToApplicationContext(w),
  128.         "childError", "class", "WidgetError",
  129.         "Children of class %s cannot be added to %n widgets",
  130.         params, &num_params);
  131.     }
  132.  
  133.     (*((CompositeWidgetClass)(boxWidgetClass->core_class.superclass))->
  134.         composite_class.insert_child) (w);
  135. }
  136.  
  137. static void Initialize(req, new, args, num_args)
  138.     Widget req, new;
  139.     ArgList args;
  140.     Cardinal *num_args;
  141. {
  142.     ((BoxWidget) new)->box.last_focus = NULL;
  143. }
  144.  
  145. static void CalculateNewSize(box, width, height)
  146.     BoxWidget box;
  147.     register Dimension *width, *height;
  148. {
  149.     register Widget child;
  150.     register int i;
  151.     int right, bottom;
  152.  
  153.     *width = *height = 0;
  154.  
  155.     for (i = 0; i < box->composite.num_children; i++) {
  156.         child = box->composite.children[i];
  157.     if (!XtIsManaged(child)) continue;
  158.     right = child->core.x + child->core.width +
  159.         2 * child->core.border_width;
  160.     bottom = child->core.y + child->core.height +
  161.         2 * child->core.border_width;
  162.     if (right > (int) *width) *width = right;
  163.     if (bottom > (int) *height) *height = bottom;
  164.     }
  165.  
  166.     *width += box->box.margin;
  167.     *height += box->box.margin;
  168.  
  169.     if (*width == 0) *width = 1;
  170.     if (*height == 0) *height = 1;
  171. }
  172.  
  173. static void ChangeManaged(w)
  174.     Widget w;
  175. {
  176.     BoxWidget box = (BoxWidget) w;
  177.     XtWidgetGeometry request;
  178.     XtGeometryResult result;
  179.  
  180.     CalculateNewSize(box, &request.width, &request.height);
  181.  
  182.     if (request.width != box->core.width ||
  183.         request.height != box->core.height) {
  184.     request.request_mode = CWWidth | CWHeight;
  185.     do {
  186.         result = XtMakeGeometryRequest(w, &request, &request);
  187.     } while (result == XtGeometryAlmost);
  188.     }
  189. }
  190.  
  191. static XtGeometryResult GeometryManager(w, desired, allowed)
  192.     Widget w;
  193.     XtWidgetGeometry *desired, *allowed;
  194. {
  195.     BoxWidget box = (BoxWidget) XtParent(w);
  196.     XtWidgetGeometry request;
  197.     XtGeometryResult result;
  198.  
  199. #define Wants(flag) (desired->request_mode & flag)
  200.  
  201.     if (Wants(XtCWQueryOnly)) return XtGeometryYes;
  202.  
  203.     if (Wants(CWWidth)) w->core.width = desired->width;
  204.     if (Wants(CWHeight)) w->core.height = desired->height;
  205.     if (Wants(CWX)) w->core.x = desired->x;
  206.     if (Wants(CWY)) w->core.y = desired->y;
  207.     if (Wants(CWBorderWidth)) {
  208.     w->core.border_width = desired->border_width;
  209.     }
  210.  
  211.     CalculateNewSize(box, &request.width, &request.height);
  212.     
  213.     if (request.width != box->core.width || 
  214.         request.height != box->core.height) {
  215.     request.request_mode = CWWidth | CWHeight;
  216.     do {
  217.         result = XtMakeGeometryRequest((Widget) box,
  218.             &request, &request);
  219.     } while (result == XtGeometryAlmost);
  220.     } 
  221.  
  222.     return XtGeometryYes;
  223.  
  224. #undef Wants
  225. }
  226.  
  227. static Boolean SetValues(old, req, new, args, num_args)
  228.     Widget old, req, new;
  229.     ArgList args;
  230.     Cardinal *num_args;
  231. {
  232.     register BoxWidget oldbox = (BoxWidget) old;
  233.     register BoxWidget newbox = (BoxWidget) new;
  234.  
  235.     if (newbox->box.margin != oldbox->box.margin ||
  236.         newbox->core.width == 0 || newbox->core.height == 0) {
  237.     CalculateNewSize(newbox, &newbox->core.width,
  238.         &newbox->core.height);
  239.     }
  240.  
  241.     return FALSE;
  242. }
  243.  
  244. static Boolean AcceptFocus(w, time)
  245.     Widget w;
  246.     Time *time;
  247. {
  248.     BoxWidget box = (BoxWidget) w;
  249.     register int i;
  250.  
  251.     if (box->box.last_focus != NULL && 
  252.         XtIsManaged(box->box.last_focus)) {
  253.     if (XtCallAcceptFocus(box->box.last_focus, time)) {
  254.         return TRUE;
  255.     }
  256.     }
  257.  
  258.     for (i = 0; i < box->composite.num_children; i++) {
  259.     if (!XtIsManaged(box->composite.children[i])) continue;
  260.     if (XtCallAcceptFocus(box->composite.children[i], time)) {
  261.         box->box.last_focus = box->composite.children[i];
  262.         return TRUE;
  263.     }
  264.     }
  265.  
  266.     box->box.last_focus = NULL;
  267.     return FALSE;
  268. }
  269. static void Redisplay(w, event, region)
  270.     Widget w;
  271.     XEvent *event;
  272.     Region region;
  273. {
  274.     CompositeWidget comp = (CompositeWidget) w;
  275.     int i;
  276.     Widget c;        /* child */
  277.  
  278.     for (i = 0; i < comp->composite.num_children; i++) {
  279.     c = comp->composite.children[i];
  280.     if (XtIsManaged(c) && XtIsSubclass(c, labelGadgetClass) &&
  281.         XRectInRegion(region, c->core.x, c->core.y,
  282.             c->core.width + 2*c->core.border_width,
  283.             c->core.height + 2*c->core.border_width)
  284.             != RectangleOut) {
  285.         (*(XtClass(c)->core_class.expose))(c, event, region);
  286.         }
  287.     }
  288. }
  289.