/* Generated by wbuild from "RowCol.w"
** (generator version $Revision: 2.0 $ of $Date: 93/07/06 16:08:04 $)
*/
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include "RowColP.h"
static void _resolve_inheritance(WidgetClass);
static void change_managed(Widget);
static void layout(Widget,int );
static XtGeometryResult  geometry_manager(Widget ,XtWidgetGeometry *,XtWidgetGeometry *);
static void resize(Widget);
static void initialize(Widget ,Widget,ArgList ,Cardinal *);
static Boolean  set_values(Widget ,Widget ,Widget,ArgList ,Cardinal *);
static char  rcsid[] = "$Header: RowCol.w,v 1.1 92/10/14 18:36:36 bert Exp $";
static void align_child(Widget,int ,int ,int ,int ,Alignment );

/*ARGSUSED*/static void align_child(Widget self, int cx, int cy, int width, int height, Alignment alignment)
{
    Position x, y;

    if (alignment & XfwfLeft) x = cx;
    else if (alignment & XfwfRight) x = cx + width - ((XfwfRowColWidget)self)->core.width;
    else x = cx + (width - ((XfwfRowColWidget)self)->core.width) / 2;
    if (alignment & XfwfTop) y = cy;
    else if (alignment & XfwfBottom) y = cy + height - ((XfwfRowColWidget)self)->core.height;
    else y = cy + (height - ((XfwfRowColWidget)self)->core.height) / 2;
    XtMoveWidget(self, x, y);
}

static XtResource resources[] = {
{XtNstoreByRow,XtCStoreByRow,XtRBoolean,sizeof(((XfwfRowColRec*)NULL)->xfwfRowCol.storeByRow),XtOffsetOf(XfwfRowColRec,xfwfRowCol.storeByRow),XtRImmediate,(XtPointer)True },
{XtNrows,XtCRows,XtRInt,sizeof(((XfwfRowColRec*)NULL)->xfwfRowCol.rows),XtOffsetOf(XfwfRowColRec,xfwfRowCol.rows),XtRImmediate,(XtPointer)0 },
{XtNcolumns,XtCColumns,XtRInt,sizeof(((XfwfRowColRec*)NULL)->xfwfRowCol.columns),XtOffsetOf(XfwfRowColRec,xfwfRowCol.columns),XtRImmediate,(XtPointer)0 },
{XtNalignment,XtCAlignment,XtRAlignment,sizeof(((XfwfRowColRec*)NULL)->xfwfRowCol.alignment),XtOffsetOf(XfwfRowColRec,xfwfRowCol.alignment),XtRImmediate,(XtPointer)XfwfTopLeft },
{XtNshrinkToFit,XtCShrinkToFit,XtRBoolean,sizeof(((XfwfRowColRec*)NULL)->xfwfRowCol.shrinkToFit),XtOffsetOf(XfwfRowColRec,xfwfRowCol.shrinkToFit),XtRImmediate,(XtPointer)False },
{XtNframeType,XtCFrameType,XtRFrameType,sizeof(((XfwfRowColRec*)NULL)->xfwfFrame.frameType),XtOffsetOf(XfwfRowColRec,xfwfFrame.frameType),XtRImmediate,(XtPointer)XfwfSunken },
{XtNframeWidth,XtCFrameWidth,XtRDimension,sizeof(((XfwfRowColRec*)NULL)->xfwfFrame.frameWidth),XtOffsetOf(XfwfRowColRec,xfwfFrame.frameWidth),XtRImmediate,(XtPointer)2 },
};

XfwfRowColClassRec xfwfRowColClassRec = {
{ /* core_class part */
(WidgetClass) &xfwfBoardClassRec,
"RowCol",
sizeof(XfwfRowColRec),
NULL,
_resolve_inheritance,
FALSE,
initialize,
NULL,
XtInheritRealize,
NULL,
0,
resources,
7,
NULLQUARK,
False ,
FALSE ,
False ,
False ,
NULL,
resize,
XtInheritExpose,
set_values,
NULL,
XtInheritSetValuesAlmost,
NULL,
XtInheritAcceptFocus,
XtVersion,
NULL,
NULL,
XtInheritQueryGeometry,
XtInheritDisplayAccelerator,
NULL 
},
{ /* composite_class part */
geometry_manager,
change_managed,
XtInheritInsertChild,
XtInheritDeleteChild,
NULL
},
{ /* XfwfCommon_class part */
XtInherit_compute_inside,
XtInherit_highlight_border,
XtInherit_unhighlight_border,
XtInherit_would_accept_focus,
XtInherit_traverse,
XtInherit_choose_color,
XtInherit_lighter_color,
XtInherit_darker_color,
NULL ,
},
{ /* XfwfFrame_class part */
0
},
{ /* XfwfBoard_class part */
XtInherit_set_abs_location,
},
{ /* XfwfRowCol_class part */
layout,
},
};
WidgetClass xfwfRowColWidgetClass = (WidgetClass) &xfwfRowColClassRec;
static void _resolve_inheritance(WidgetClass class)
{
  XfwfRowColWidgetClass c = (XfwfRowColWidgetClass) class;
  XfwfRowColWidgetClass super;
  static CompositeClassExtensionRec extension_rec = {
    NULL, NULLQUARK, XtCompositeExtensionVersion,
    sizeof(CompositeClassExtensionRec), True};
  CompositeClassExtensionRec *ext;
  ext = (XtPointer)XtMalloc(sizeof(*ext));
  *ext = extension_rec;
  ext->next_extension = c->composite_class.extension;
  c->composite_class.extension = ext;
  if (class == xfwfRowColWidgetClass) return;
  super = (XfwfRowColWidgetClass)class->core_class.superclass;
  if (c->xfwfRowCol_class.layout == XtInherit_layout)
    c->xfwfRowCol_class.layout = super->xfwfRowCol_class.layout;
}
/*ARGSUSED*/static void change_managed(Widget self)
{
    ((XfwfRowColWidgetClass)self->core.widget_class)->xfwfRowCol_class.layout(self, ((XfwfRowColWidget)self)->xfwfRowCol.shrinkToFit);
}
/*ARGSUSED*/static void layout(Widget self, int shrink)
{
    int nrows, ncols, i, nchild, n;
    Position left, top, x, y;
    Dimension width, height, w, h;
    Widget child;

    nchild = 0;
    ((XfwfRowColWidget)self)->xfwfRowCol.max_width = 0;
    ((XfwfRowColWidget)self)->xfwfRowCol.max_height = 0;

    for (i = 0; i < ((XfwfRowColWidget)self)->composite.num_children; i++) {
	child = ((XfwfRowColWidget)self)->composite.children[i];
	if (! XtIsManaged(child)) continue;
	nchild++;
	((XfwfRowColWidget)self)->xfwfRowCol.max_width =
	    max(((XfwfRowColWidget)self)->xfwfRowCol.max_width,
	    ((XfwfRowColWidget)child)->core.width +
	    2*((XfwfRowColWidget)child)->core.border_width);
	((XfwfRowColWidget)self)->xfwfRowCol.max_height =
	    max(((XfwfRowColWidget)self)->xfwfRowCol.max_height,
	    ((XfwfRowColWidget)child)->core.height +
	    2*((XfwfRowColWidget)child)->core.border_width);
    }

    ((XfwfRowColWidgetClass)self->core.widget_class)->xfwfCommon_class.compute_inside(self, &left, &top, &width, &height);

    /* If there is a single child resize it to fill the window instead of
     * laying out multiple child widgets.  This allows a group widget to be
     * used to draw a labeled frame around a composite child.  09Mar94 DCT.
     */
    if (((XfwfRowColWidget)self)->composite.num_children == 1) {
	if (width > 0 && width < 16384 && height > 0 && height < 16384) {
	    /* Don't resize child if parent doesn't have a size yet.
	     */
	    child = ((XfwfRowColWidget)self)->composite.children[0];
	    w = width - 2 * child->core.border_width;
	    h = height - 2 * child->core.border_width;

	    XtResizeWidget (child, w, h,
		((XfwfRowColWidget)child)->core.border_width);
	    align_child (child, left, top, w, h, XfwfLeft|XfwfTop);

	    ((XfwfRowColWidget)self)->xfwfRowCol.max_width =
		child->core.width - 2 * child->core.border_width;
	    ((XfwfRowColWidget)self)->xfwfRowCol.max_height =
		child->core.height - 2 * child->core.border_width;

	    nrows = ncols = 1;
	    goto do_shrink;
	}
    }

    if (((XfwfRowColWidget)self)->xfwfRowCol.columns != 0) {
	ncols = ((XfwfRowColWidget)self)->xfwfRowCol.columns;
	nrows = (nchild + ncols - 1)/ncols;
    } else if (((XfwfRowColWidget)self)->xfwfRowCol.rows != 0) {
	nrows = ((XfwfRowColWidget)self)->xfwfRowCol.rows;
	ncols = (nchild + nrows - 1)/nrows;
    } else if (((XfwfRowColWidget)self)->composite.num_children == 1) {
	/* 09Mar94 DCT */
	nrows = ncols = 1;
    } else {
	ncols = ((XfwfRowColWidget)self)->xfwfRowCol.max_width != 0 ? width/((XfwfRowColWidget)self)->xfwfRowCol.max_width : 1;
	if (ncols == 0) ncols = 1;
	nrows = (nchild + ncols - 1)/ncols;
    }

    x = left;
    y = top;
    n = 0;
    if (((XfwfRowColWidget)self)->xfwfRowCol.storeByRow) {
	for (i = 0; i < ((XfwfRowColWidget)self)->composite.num_children; i++) {
	    child = ((XfwfRowColWidget)self)->composite.children[i];
	    if (! XtIsManaged(child)) continue;
	    align_child(child, x, y, ((XfwfRowColWidget)self)->xfwfRowCol.max_width, ((XfwfRowColWidget)self)->xfwfRowCol.max_height, ((XfwfRowColWidget)self)->xfwfRowCol.alignment);
	    n++;
	    if (n == ncols) {
		n = 0;
		x = left;
		y += ((XfwfRowColWidget)self)->xfwfRowCol.max_height;
	    } else
		x += ((XfwfRowColWidget)self)->xfwfRowCol.max_width;
	}
    } else {
	for (i = 0; i < ((XfwfRowColWidget)self)->composite.num_children; i++) {
	    child = ((XfwfRowColWidget)self)->composite.children[i];
	    if (! XtIsManaged(child)) continue;
	    align_child(child, x, y, ((XfwfRowColWidget)self)->xfwfRowCol.max_width, ((XfwfRowColWidget)self)->xfwfRowCol.max_height, ((XfwfRowColWidget)self)->xfwfRowCol.alignment);
	    n++;
	    if (n == nrows) {
		n = 0;
		y = top;
		x += ((XfwfRowColWidget)self)->xfwfRowCol.max_width;
	    } else
		y += ((XfwfRowColWidget)self)->xfwfRowCol.max_height;
	}
    }

do_shrink:
    if (shrink) {
	w = 2*left + ncols * ((XfwfRowColWidget)self)->xfwfRowCol.max_width;
	h = 2*top + nrows * ((XfwfRowColWidget)self)->xfwfRowCol.max_height;
	if (((XfwfRowColWidget)self)->xfwfRowCol.columns != 0)
	    XtVaSetValues(self, XtNwidth, w, XtNheight, h, NULL);
	else
	    XtVaSetValues(self, XtNheight, h, NULL);
    }
}


/*ARGSUSED*/static XtGeometryResult
geometry_manager (Widget child, XtWidgetGeometry *request, XtWidgetGeometry *reply)
{
    Widget self = XtParent(child);
    Dimension newwd, newht, newbd;

    if (request->request_mode & (CWX | CWY))
	return XtGeometryNo;
    if (request->request_mode & XtCWQueryOnly)
	return XtGeometryYes;

    newwd = request->request_mode & CWWidth ?
	request->width : ((XfwfRowColWidget)child)->core.width;
    newht = request->request_mode & CWHeight ?
	request->height : ((XfwfRowColWidget)child)->core.height;
    newbd = request->request_mode & CWBorderWidth ?
	request->border_width : ((XfwfRowColWidget)child)->core.border_width;

    if (newwd == ((XfwfRowColWidget)child)->core.width &&
	newht == ((XfwfRowColWidget)child)->core.height &&
	newbd == ((XfwfRowColWidget)child)->core.border_width)
	return XtGeometryNo;

    XtResizeWidget(child, newwd, newht, newbd);

    ((XfwfRowColWidgetClass)self->core.widget_class)->xfwfRowCol_class.layout
	(self, ((XfwfRowColWidget)self)->xfwfRowCol.shrinkToFit);

    /* Since layout can resize the child widget it isn't appropriate to just
     * return XtGeometryDone here, as the FWF code does.  17Mar94 DCT.
     */
    if (newwd == ((XfwfRowColWidget)child)->core.width &&
	newht == ((XfwfRowColWidget)child)->core.height &&
	newbd == ((XfwfRowColWidget)child)->core.border_width) {

	return XtGeometryDone;

    } else {
	reply->request_mode = 0;
	if (newwd != child->core.width) {
	    reply->request_mode |= CWWidth;
	    reply->width = child->core.width;
	}
	if (newht != child->core.height) {
	    reply->request_mode |= CWHeight;
	    reply->height = child->core.height;
	}

	return XtGeometryAlmost;
    }
}

/*ARGSUSED*/static void resize(Widget self)
{
    if (((XfwfRowColWidget)self)->xfwfRowCol.rows == 0 && ((XfwfRowColWidget)self)->xfwfRowCol.columns == 0) ((XfwfRowColWidgetClass)self->core.widget_class)->xfwfRowCol_class.layout(self, False);
}
/*ARGSUSED*/static void initialize(Widget request, Widget self, ArgList args, Cardinal *num_args)
{
    ((XfwfRowColWidget)self)->xfwfRowCol.max_width = ((XfwfRowColWidget)self)->xfwfRowCol.max_height = 0;
}
/*ARGSUSED*/static Boolean  set_values(Widget old, Widget request, Widget self, ArgList args, Cardinal *num_args)
{
    Boolean need_layout = False;
    Boolean need_redisplay = False;

    if (((XfwfRowColWidget)old)->xfwfRowCol.storeByRow != ((XfwfRowColWidget)self)->xfwfRowCol.storeByRow) need_layout = True;
    if (((XfwfRowColWidget)old)->xfwfRowCol.rows != ((XfwfRowColWidget)self)->xfwfRowCol.rows) need_layout = True;
    if (((XfwfRowColWidget)old)->xfwfRowCol.columns != ((XfwfRowColWidget)self)->xfwfRowCol.columns) need_layout = True;
    if (((XfwfRowColWidget)old)->xfwfRowCol.alignment != ((XfwfRowColWidget)self)->xfwfRowCol.alignment) need_layout = True;
    if (((XfwfRowColWidget)old)->xfwfRowCol.shrinkToFit != ((XfwfRowColWidget)self)->xfwfRowCol.shrinkToFit) need_layout = True;
    if (need_layout) {
	((XfwfRowColWidgetClass)self->core.widget_class)->xfwfRowCol_class.layout(self, ((XfwfRowColWidget)self)->xfwfRowCol.shrinkToFit);
	need_redisplay = True;
    }
    return need_redisplay;
}
