File:  [Research Unix] / researchv9 / X11 / src / X.V11R1 / lib / Xtk / ButtonBox.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:22:00 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv9-SUN3_old, researchv9-SUN3, HEAD
researchv9-SUN3(old)

#ifndef lint
static char rcsid[] = "$Header: /var/lib/cvsd/repos/research/researchv9/X11/src/X.V11R1/lib/Xtk/ButtonBox.c,v 1.1.1.1 2018/04/24 17:22:00 root Exp $";
#endif lint

/*
 * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
 * 
 *                         All Rights Reserved
 * 
 * Permission to use, copy, modify, and distribute this software and its 
 * documentation for any purpose and without fee is hereby granted, 
 * provided that the above copyright notice appear in all copies and that
 * both that copyright notice and this permission notice appear in 
 * supporting documentation, and that the name of Digital Equipment
 * Corporation not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior permission.  
 * 
 * 
 * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */
/* 
 * ButtonBox.c - Button box composite widget
 * 
 * Author:	Joel McCormack
 * 		Digital Equipment Corporation
 * 		Western Research Laboratory
 * Date:	Mon Aug 31 1987
 *
 */

#include	"Intrinsic.h"
#include	"ButtonBox.h"
#include	"ButtonBoxP.h"
#include	"Atoms.h"
#include	"Misc.h"

/****************************************************************
 *
 * ButtonBox Resources
 *
 ****************************************************************/

static XtResource resources[] = {
    {XtNhSpace, XtCHSpace, XrmRInt, sizeof(int),
	 XtOffset(ButtonBoxWidget, button_box.h_space), XtRString, "4"},
    {XtNvSpace, XtCVSpace, XrmRInt, sizeof(int),
	 XtOffset(ButtonBoxWidget, button_box.v_space), XtRString, "4"},
};

/****************************************************************
 *
 * Full class record constant
 *
 ****************************************************************/

static void Initialize();
static void Realize();
static void Resize();
static Boolean SetValues();
static XtGeometryResult GeometryManager();
static void ChangeManaged();
static void ClassInitialize();

ButtonBoxClassRec buttonBoxClassRec = {
  {
/* core_class fields      */
    /* superclass         */    (WidgetClass) &compositeClassRec,
    /* class_name         */    "ButtonBox",
    /* widget_size        */    sizeof(ButtonBoxRec),
    /* class_initialize   */    ClassInitialize,
    /* class_inited       */	FALSE,
    /* initialize         */    Initialize,
    /* realize            */    Realize,
    /* actions            */    NULL,
    /* num_actions	  */	0,
    /* resources          */    resources,
    /* num_resources      */    XtNumber(resources),
    /* xrm_class          */    NULLQUARK,
    /* compress_motion	  */	TRUE,
    /* compress_exposure  */	TRUE,
    /* visible_interest   */    FALSE,
    /* destroy            */    NULL,
    /* resize             */    Resize,
    /* expose             */    NULL,
    /* set_values         */    SetValues,
    /* accept_focus       */    NULL
  },{
/* composite_class fields */
    /* geometry_manager   */    GeometryManager,
    /* change_managed     */    ChangeManaged,
    /* insert_child	  */	NULL,	/* Inherit from superclass */
    /* delete_child	  */	NULL,	/* Inherit from superclass */
    /* move_focus_to_next */    NULL,
    /* move_focus_to_prev */    NULL
  },{
    /* mumble		  */	0	/* Make C compiler happy   */
  }
};

WidgetClass buttonBoxWidgetClass = (WidgetClass)&buttonBoxClassRec;


/****************************************************************
 *
 * Private Routines
 *
 ****************************************************************/

static void ClassInitialize()
{
    CompositeWidgetClass superclass;
    ButtonBoxWidgetClass myclass;

    myclass = (ButtonBoxWidgetClass) buttonBoxWidgetClass;
    superclass = (CompositeWidgetClass) myclass->core_class.superclass;

    /* Inherit insert_child and delete_child from Composite */
    myclass->composite_class.insert_child =
        superclass->composite_class.insert_child;
    myclass->composite_class.delete_child =
        superclass->composite_class.delete_child;
}

/*
 *
 * Do a layout, either actually assigning positions, or just calculating size.
 * Returns TRUE on success; FALSE if it couldn't make things fit.
 *
 */

/* ARGSUSED */
static DoLayout(bbw, width, height, replyWidth, replyHeight, position)
    ButtonBoxWidget	bbw;
    Dimension		width, height;
    Dimension		*replyWidth, *replyHeight;	/* RETURN */
    Boolean		position;	/* actually reposition the windows? */
{
    Cardinal  i;
    Dimension w, h;	/* Width and height needed for button box 	*/
    Dimension lw, lh;	/* Width and height needed for current line 	*/
    Dimension bw, bh;	/* Width and height needed for current button 	*/
    Dimension h_space;  /* Local copy of bbw->buttonBox.h_space 	*/
    Widget    widget;	/* Current button 				*/

    /* ButtonBox width and height */
    h_space = bbw->button_box.h_space;
    w = h_space;
    h = bbw->button_box.v_space;
   
    /* Line width and height */
    lh = 0;
    lw = h_space;
  
    for (i = 0; i < bbw->composite.num_children; i++) {
	widget = bbw->composite.children[i];
	if (widget->core.managed) {
	    /* Compute button width */
	    bw = widget->core.width + 2*widget->core.border_width + h_space;
	    if ((lw + bw > width) && (lw > h_space)) {
		/* At least one button on this line, and can't fit any more.
		   Start new line */
		AssignMax(w, lw);
		h += lh + bbw->button_box.v_space;
		lh = 0;
		lw = h_space;
	    }
	    if (position && (lw != widget->core.x || h != widget->core.y)) {
		XtMoveWidget(bbw->composite.children[i], (int)lw, (int)h);
	    }
	    lw += bw;
	    bh = widget->core.height + 2*widget->core.border_width;
	    AssignMax(lh, bh);
	} /* if managed */
    } /* for */

    /* Finish off last line */
    if (lw > h_space) {
	AssignMax(w, lw);
        h += lh + bbw->button_box.v_space;
    }

    *replyWidth = w;
    *replyHeight = h;
}

/*
 *
 * Calculate preferred size, given constraining box
 *
 */

static Boolean PreferredSize(bbw, width, height, replyWidth, replyHeight)
    ButtonBoxWidget	bbw;
    Dimension		width, height;
    Dimension		*replyWidth, *replyHeight;
{
    DoLayout(bbw, width, height, replyWidth, replyHeight, FALSE);
    return ((*replyWidth <= width) && (*replyHeight <= height));
}

/*
 *
 * Actually layout the button box
 *
 */

static void Resize(bbw)
    ButtonBoxWidget	bbw;
{
    Dimension junk;

    DoLayout(bbw, bbw->core.width, bbw->core.height, &junk, &junk, TRUE);
} /* Resize */

/*
 *
 * Try to do a new layout within the current width and height;
 * if that fails try to do it within the box returned by PreferredSize.
 *
 * TryNewLayout just says if it's possible, and doesn't actually move the kids
 */

static Boolean TryNewLayout(bbw)
    ButtonBoxWidget	bbw;
{
    Dimension		width, height;

    if (!PreferredSize(bbw, bbw->core.width, bbw->core.height, &width, &height))
	(void) PreferredSize(bbw, width, height, &width, &height);

    if ((bbw->core.width == width) && (bbw->core.height == height)) {
        /* Same size */
	return (TRUE);
    }

    /* let's see if our parent will go for a new size. */
    switch (XtMakeResizeRequest((Widget) bbw, width, height, &width, &height)) {

	case XtGeometryYes:
	    return (TRUE);

	case XtGeometryNo:
	    return (FALSE);

	case XtGeometryAlmost:
	    if (! PreferredSize(bbw, width, height, &width, &height))
	        return (FALSE);
	    (void) XtMakeResizeRequest((Widget) bbw, width, height, 
					&width, &height);
	    return (TRUE);
    }
}

/*
 *
 * Geometry Manager
 *
 */

/*ARGSUSED*/
static XtGeometryResult GeometryManager(w, request, reply)
    Widget		w;
    XtWidgetGeometry	*request;
    XtWidgetGeometry	*reply;	/* RETURN */

{
    Dimension	width, height, borderWidth, junk;
    ButtonBoxWidget bbw;

    /* Position request always denied */
    if (request->request_mode & (CWX | CWY))
        return (XtGeometryNo);

    /* Size changes must see if the new size can be accomodated */
    if (request->request_mode & (CWWidth | CWHeight | CWBorderWidth)) {

	/* Make all three fields in the request valid */
	if ((request->request_mode & CWWidth) == 0)
	    request->width = w->core.width;
	if ((request->request_mode & CWHeight) == 0)
	    request->height = w->core.height;
        if ((request->request_mode & CWBorderWidth) == 0)
	    request->border_width = w->core.border_width;

	/* Save current size and set to new size */
	width = w->core.width;
	height = w->core.height;
	borderWidth = w->core.border_width;
	w->core.width = request->width;
	w->core.height = request->height;
	w->core.border_width = request->border_width;

	/* Decide if new layout works: (1) new button is smaller,
	   (2) new button fits in existing ButtonBox, (3) ButtonBox can be
	   expanded to allow new button to fit */

	bbw = (ButtonBoxWidget) w->core.parent;
	if (((request->width + request->border_width <= width + borderWidth) &&
	    (request->height + request->border_width <= height + borderWidth))
	|| PreferredSize(bbw, bbw->core.width, bbw->core.height, &junk, &junk)
	|| TryNewLayout(bbw)) {
	    /* Fits in existing or new space, relayout */
	    Resize(bbw);
	    return (XtGeometryYes);
	} else {
	    /* Cannot satisfy request, change back to original geometry */
	    w->core.width = width;
	    w->core.height = height;
	    w->core.border_width = borderWidth;
	    return (XtGeometryNo);
	}
    }; /* if any size changes requested */

    /* Any stacking changes don't make a difference, so allow if that's all */
    return (XtGeometryYes);
}

static void ChangeManaged(bbw)
    ButtonBoxWidget bbw;
{
    /* Reconfigure the button box */
    (void) TryNewLayout(bbw);
    Resize(bbw);
}

static void Initialize(request, new, args, num_args)
    ButtonBoxWidget request, new;
    ArgList args;
    Cardinal num_args;
{
/* ||| What are consequences of letting height, width be 0? If okay, then
       Initialize can be NULL */

    if (new->core.width == 0)
        new->core.width =
	    ((new->button_box.h_space != 0) ? new->button_box.h_space : 10);
    if (new->core.height == 0)
	new->core.height = 
	    ((new->button_box.v_space != 0) ? new->button_box.v_space : 10);
} /* Initialize */

/* ||| Should Realize just return a modified mask and attributes?  Or will some
   of the other parameters change from class to class? */
static void Realize(w, valueMask, attributes)
    register Widget w;
    Mask valueMask;
    XSetWindowAttributes *attributes;
{
    attributes->bit_gravity = NorthWestGravity;
    valueMask |= CWBitGravity;
    
    w->core.window =
	XCreateWindow(XtDisplay(w), XtWindow(w->core.parent),
	w->core.x, w->core.y, w->core.width, w->core.height,
	w->core.border_width, w->core.depth,
	InputOutput, (Visual *)CopyFromParent,
	valueMask, attributes);
} /* Realize */

/*
 *
 * Set Values
 *
 */

static Boolean SetValues (current, request, new, last)
    ButtonBoxWidget current, request, new;
    Boolean last;
{
    /* ||| Old code completely bogus, need background, etc., then
    XtMakeGeometryRequest, then relayout */
    return (FALSE);
}


unix.superglobalmegacorp.com

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