Annotation of researchv9/X11/src/X.V11R1/lib/Xtk/ButtonBox.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char rcsid[] = "$Header: ButtonBox.c,v 1.13 87/09/13 20:35:58 newman Exp $";
                      3: #endif lint
                      4: 
                      5: /*
                      6:  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
                      7:  * 
                      8:  *                         All Rights Reserved
                      9:  * 
                     10:  * Permission to use, copy, modify, and distribute this software and its 
                     11:  * documentation for any purpose and without fee is hereby granted, 
                     12:  * provided that the above copyright notice appear in all copies and that
                     13:  * both that copyright notice and this permission notice appear in 
                     14:  * supporting documentation, and that the name of Digital Equipment
                     15:  * Corporation not be used in advertising or publicity pertaining to
                     16:  * distribution of the software without specific, written prior permission.  
                     17:  * 
                     18:  * 
                     19:  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     20:  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     21:  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     22:  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     23:  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     24:  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     25:  * SOFTWARE.
                     26:  */
                     27: /* 
                     28:  * ButtonBox.c - Button box composite widget
                     29:  * 
                     30:  * Author:     Joel McCormack
                     31:  *             Digital Equipment Corporation
                     32:  *             Western Research Laboratory
                     33:  * Date:       Mon Aug 31 1987
                     34:  *
                     35:  */
                     36: 
                     37: #include       "Intrinsic.h"
                     38: #include       "ButtonBox.h"
                     39: #include       "ButtonBoxP.h"
                     40: #include       "Atoms.h"
                     41: #include       "Misc.h"
                     42: 
                     43: /****************************************************************
                     44:  *
                     45:  * ButtonBox Resources
                     46:  *
                     47:  ****************************************************************/
                     48: 
                     49: static XtResource resources[] = {
                     50:     {XtNhSpace, XtCHSpace, XrmRInt, sizeof(int),
                     51:         XtOffset(ButtonBoxWidget, button_box.h_space), XtRString, "4"},
                     52:     {XtNvSpace, XtCVSpace, XrmRInt, sizeof(int),
                     53:         XtOffset(ButtonBoxWidget, button_box.v_space), XtRString, "4"},
                     54: };
                     55: 
                     56: /****************************************************************
                     57:  *
                     58:  * Full class record constant
                     59:  *
                     60:  ****************************************************************/
                     61: 
                     62: static void Initialize();
                     63: static void Realize();
                     64: static void Resize();
                     65: static Boolean SetValues();
                     66: static XtGeometryResult GeometryManager();
                     67: static void ChangeManaged();
                     68: static void ClassInitialize();
                     69: 
                     70: ButtonBoxClassRec buttonBoxClassRec = {
                     71:   {
                     72: /* core_class fields      */
                     73:     /* superclass         */    (WidgetClass) &compositeClassRec,
                     74:     /* class_name         */    "ButtonBox",
                     75:     /* widget_size        */    sizeof(ButtonBoxRec),
                     76:     /* class_initialize   */    ClassInitialize,
                     77:     /* class_inited       */   FALSE,
                     78:     /* initialize         */    Initialize,
                     79:     /* realize            */    Realize,
                     80:     /* actions            */    NULL,
                     81:     /* num_actions       */    0,
                     82:     /* resources          */    resources,
                     83:     /* num_resources      */    XtNumber(resources),
                     84:     /* xrm_class          */    NULLQUARK,
                     85:     /* compress_motion   */    TRUE,
                     86:     /* compress_exposure  */   TRUE,
                     87:     /* visible_interest   */    FALSE,
                     88:     /* destroy            */    NULL,
                     89:     /* resize             */    Resize,
                     90:     /* expose             */    NULL,
                     91:     /* set_values         */    SetValues,
                     92:     /* accept_focus       */    NULL
                     93:   },{
                     94: /* composite_class fields */
                     95:     /* geometry_manager   */    GeometryManager,
                     96:     /* change_managed     */    ChangeManaged,
                     97:     /* insert_child      */    NULL,   /* Inherit from superclass */
                     98:     /* delete_child      */    NULL,   /* Inherit from superclass */
                     99:     /* move_focus_to_next */    NULL,
                    100:     /* move_focus_to_prev */    NULL
                    101:   },{
                    102:     /* mumble            */    0       /* Make C compiler happy   */
                    103:   }
                    104: };
                    105: 
                    106: WidgetClass buttonBoxWidgetClass = (WidgetClass)&buttonBoxClassRec;
                    107: 
                    108: 
                    109: /****************************************************************
                    110:  *
                    111:  * Private Routines
                    112:  *
                    113:  ****************************************************************/
                    114: 
                    115: static void ClassInitialize()
                    116: {
                    117:     CompositeWidgetClass superclass;
                    118:     ButtonBoxWidgetClass myclass;
                    119: 
                    120:     myclass = (ButtonBoxWidgetClass) buttonBoxWidgetClass;
                    121:     superclass = (CompositeWidgetClass) myclass->core_class.superclass;
                    122: 
                    123:     /* Inherit insert_child and delete_child from Composite */
                    124:     myclass->composite_class.insert_child =
                    125:         superclass->composite_class.insert_child;
                    126:     myclass->composite_class.delete_child =
                    127:         superclass->composite_class.delete_child;
                    128: }
                    129: 
                    130: /*
                    131:  *
                    132:  * Do a layout, either actually assigning positions, or just calculating size.
                    133:  * Returns TRUE on success; FALSE if it couldn't make things fit.
                    134:  *
                    135:  */
                    136: 
                    137: /* ARGSUSED */
                    138: static DoLayout(bbw, width, height, replyWidth, replyHeight, position)
                    139:     ButtonBoxWidget    bbw;
                    140:     Dimension          width, height;
                    141:     Dimension          *replyWidth, *replyHeight;      /* RETURN */
                    142:     Boolean            position;       /* actually reposition the windows? */
                    143: {
                    144:     Cardinal  i;
                    145:     Dimension w, h;    /* Width and height needed for button box       */
                    146:     Dimension lw, lh;  /* Width and height needed for current line     */
                    147:     Dimension bw, bh;  /* Width and height needed for current button   */
                    148:     Dimension h_space;  /* Local copy of bbw->buttonBox.h_space        */
                    149:     Widget    widget;  /* Current button                               */
                    150: 
                    151:     /* ButtonBox width and height */
                    152:     h_space = bbw->button_box.h_space;
                    153:     w = h_space;
                    154:     h = bbw->button_box.v_space;
                    155:    
                    156:     /* Line width and height */
                    157:     lh = 0;
                    158:     lw = h_space;
                    159:   
                    160:     for (i = 0; i < bbw->composite.num_children; i++) {
                    161:        widget = bbw->composite.children[i];
                    162:        if (widget->core.managed) {
                    163:            /* Compute button width */
                    164:            bw = widget->core.width + 2*widget->core.border_width + h_space;
                    165:            if ((lw + bw > width) && (lw > h_space)) {
                    166:                /* At least one button on this line, and can't fit any more.
                    167:                   Start new line */
                    168:                AssignMax(w, lw);
                    169:                h += lh + bbw->button_box.v_space;
                    170:                lh = 0;
                    171:                lw = h_space;
                    172:            }
                    173:            if (position && (lw != widget->core.x || h != widget->core.y)) {
                    174:                XtMoveWidget(bbw->composite.children[i], (int)lw, (int)h);
                    175:            }
                    176:            lw += bw;
                    177:            bh = widget->core.height + 2*widget->core.border_width;
                    178:            AssignMax(lh, bh);
                    179:        } /* if managed */
                    180:     } /* for */
                    181: 
                    182:     /* Finish off last line */
                    183:     if (lw > h_space) {
                    184:        AssignMax(w, lw);
                    185:         h += lh + bbw->button_box.v_space;
                    186:     }
                    187: 
                    188:     *replyWidth = w;
                    189:     *replyHeight = h;
                    190: }
                    191: 
                    192: /*
                    193:  *
                    194:  * Calculate preferred size, given constraining box
                    195:  *
                    196:  */
                    197: 
                    198: static Boolean PreferredSize(bbw, width, height, replyWidth, replyHeight)
                    199:     ButtonBoxWidget    bbw;
                    200:     Dimension          width, height;
                    201:     Dimension          *replyWidth, *replyHeight;
                    202: {
                    203:     DoLayout(bbw, width, height, replyWidth, replyHeight, FALSE);
                    204:     return ((*replyWidth <= width) && (*replyHeight <= height));
                    205: }
                    206: 
                    207: /*
                    208:  *
                    209:  * Actually layout the button box
                    210:  *
                    211:  */
                    212: 
                    213: static void Resize(bbw)
                    214:     ButtonBoxWidget    bbw;
                    215: {
                    216:     Dimension junk;
                    217: 
                    218:     DoLayout(bbw, bbw->core.width, bbw->core.height, &junk, &junk, TRUE);
                    219: } /* Resize */
                    220: 
                    221: /*
                    222:  *
                    223:  * Try to do a new layout within the current width and height;
                    224:  * if that fails try to do it within the box returned by PreferredSize.
                    225:  *
                    226:  * TryNewLayout just says if it's possible, and doesn't actually move the kids
                    227:  */
                    228: 
                    229: static Boolean TryNewLayout(bbw)
                    230:     ButtonBoxWidget    bbw;
                    231: {
                    232:     Dimension          width, height;
                    233: 
                    234:     if (!PreferredSize(bbw, bbw->core.width, bbw->core.height, &width, &height))
                    235:        (void) PreferredSize(bbw, width, height, &width, &height);
                    236: 
                    237:     if ((bbw->core.width == width) && (bbw->core.height == height)) {
                    238:         /* Same size */
                    239:        return (TRUE);
                    240:     }
                    241: 
                    242:     /* let's see if our parent will go for a new size. */
                    243:     switch (XtMakeResizeRequest((Widget) bbw, width, height, &width, &height)) {
                    244: 
                    245:        case XtGeometryYes:
                    246:            return (TRUE);
                    247: 
                    248:        case XtGeometryNo:
                    249:            return (FALSE);
                    250: 
                    251:        case XtGeometryAlmost:
                    252:            if (! PreferredSize(bbw, width, height, &width, &height))
                    253:                return (FALSE);
                    254:            (void) XtMakeResizeRequest((Widget) bbw, width, height, 
                    255:                                        &width, &height);
                    256:            return (TRUE);
                    257:     }
                    258: }
                    259: 
                    260: /*
                    261:  *
                    262:  * Geometry Manager
                    263:  *
                    264:  */
                    265: 
                    266: /*ARGSUSED*/
                    267: static XtGeometryResult GeometryManager(w, request, reply)
                    268:     Widget             w;
                    269:     XtWidgetGeometry   *request;
                    270:     XtWidgetGeometry   *reply; /* RETURN */
                    271: 
                    272: {
                    273:     Dimension  width, height, borderWidth, junk;
                    274:     ButtonBoxWidget bbw;
                    275: 
                    276:     /* Position request always denied */
                    277:     if (request->request_mode & (CWX | CWY))
                    278:         return (XtGeometryNo);
                    279: 
                    280:     /* Size changes must see if the new size can be accomodated */
                    281:     if (request->request_mode & (CWWidth | CWHeight | CWBorderWidth)) {
                    282: 
                    283:        /* Make all three fields in the request valid */
                    284:        if ((request->request_mode & CWWidth) == 0)
                    285:            request->width = w->core.width;
                    286:        if ((request->request_mode & CWHeight) == 0)
                    287:            request->height = w->core.height;
                    288:         if ((request->request_mode & CWBorderWidth) == 0)
                    289:            request->border_width = w->core.border_width;
                    290: 
                    291:        /* Save current size and set to new size */
                    292:        width = w->core.width;
                    293:        height = w->core.height;
                    294:        borderWidth = w->core.border_width;
                    295:        w->core.width = request->width;
                    296:        w->core.height = request->height;
                    297:        w->core.border_width = request->border_width;
                    298: 
                    299:        /* Decide if new layout works: (1) new button is smaller,
                    300:           (2) new button fits in existing ButtonBox, (3) ButtonBox can be
                    301:           expanded to allow new button to fit */
                    302: 
                    303:        bbw = (ButtonBoxWidget) w->core.parent;
                    304:        if (((request->width + request->border_width <= width + borderWidth) &&
                    305:            (request->height + request->border_width <= height + borderWidth))
                    306:        || PreferredSize(bbw, bbw->core.width, bbw->core.height, &junk, &junk)
                    307:        || TryNewLayout(bbw)) {
                    308:            /* Fits in existing or new space, relayout */
                    309:            Resize(bbw);
                    310:            return (XtGeometryYes);
                    311:        } else {
                    312:            /* Cannot satisfy request, change back to original geometry */
                    313:            w->core.width = width;
                    314:            w->core.height = height;
                    315:            w->core.border_width = borderWidth;
                    316:            return (XtGeometryNo);
                    317:        }
                    318:     }; /* if any size changes requested */
                    319: 
                    320:     /* Any stacking changes don't make a difference, so allow if that's all */
                    321:     return (XtGeometryYes);
                    322: }
                    323: 
                    324: static void ChangeManaged(bbw)
                    325:     ButtonBoxWidget bbw;
                    326: {
                    327:     /* Reconfigure the button box */
                    328:     (void) TryNewLayout(bbw);
                    329:     Resize(bbw);
                    330: }
                    331: 
                    332: static void Initialize(request, new, args, num_args)
                    333:     ButtonBoxWidget request, new;
                    334:     ArgList args;
                    335:     Cardinal num_args;
                    336: {
                    337: /* ||| What are consequences of letting height, width be 0? If okay, then
                    338:        Initialize can be NULL */
                    339: 
                    340:     if (new->core.width == 0)
                    341:         new->core.width =
                    342:            ((new->button_box.h_space != 0) ? new->button_box.h_space : 10);
                    343:     if (new->core.height == 0)
                    344:        new->core.height = 
                    345:            ((new->button_box.v_space != 0) ? new->button_box.v_space : 10);
                    346: } /* Initialize */
                    347: 
                    348: /* ||| Should Realize just return a modified mask and attributes?  Or will some
                    349:    of the other parameters change from class to class? */
                    350: static void Realize(w, valueMask, attributes)
                    351:     register Widget w;
                    352:     Mask valueMask;
                    353:     XSetWindowAttributes *attributes;
                    354: {
                    355:     attributes->bit_gravity = NorthWestGravity;
                    356:     valueMask |= CWBitGravity;
                    357:     
                    358:     w->core.window =
                    359:        XCreateWindow(XtDisplay(w), XtWindow(w->core.parent),
                    360:        w->core.x, w->core.y, w->core.width, w->core.height,
                    361:        w->core.border_width, w->core.depth,
                    362:        InputOutput, (Visual *)CopyFromParent,
                    363:        valueMask, attributes);
                    364: } /* Realize */
                    365: 
                    366: /*
                    367:  *
                    368:  * Set Values
                    369:  *
                    370:  */
                    371: 
                    372: static Boolean SetValues (current, request, new, last)
                    373:     ButtonBoxWidget current, request, new;
                    374:     Boolean last;
                    375: {
                    376:     /* ||| Old code completely bogus, need background, etc., then
                    377:     XtMakeGeometryRequest, then relayout */
                    378:     return (FALSE);
                    379: }
                    380: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.