[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference bulova::decw_jan-89_to_nov-90

Title:DECWINDOWS 26-JAN-89 to 29-NOV-90
Notice:See 1639.0 for VMS V5.3 kit; 2043.0 for 5.4 IFT kit
Moderator:STAR::VATNE
Created:Mon Oct 30 1989
Last Modified:Mon Dec 31 1990
Last Successful Update:Fri Jun 06 1997
Number of topics:3726
Total number of notes:19516

2452.0. "Prob: Clients resource values not recognized at widget instance initialization" by MDVAX3::WALTON () Thu Mar 15 1990 12:50

I am attempting to write my first widget called the Rectangular Array widget
(RectArray),  but I am having a problem.  Before I describe the problem, I 
will briefly describe the functionality of the widget.

The RectArray widget, when completed, will arrange its children in a 
rectangular array.  The resources for the RectArray widget are 

    child_height:	height of all children
    child_width:	width of all children
    margin_width:	distance between children at the edge of the matrix
    			of children and the edge of the RectArray widget
    child_gap:		distance between children
    fill_start:		specifies the corner at which the first child should 
    			be placed.
    fill_direction:	from the start point, in which direction should 
    			successive children fill the RectArray widget


For example, the following RectArray widget has 13 children.  The first
one was placed in the lower left corner.  In general, the RectArray widget
is filling from bottom to top, so the fill_direction would be UpDown.


    +-------------------------------------------------------------+
    |                                                             | 
    |                                                             | 
    |                                                             | 
    |                                                             | 
    |   +-----+     +-----+     +-----+                           | 
    |	| 11  |     | 12  |     | 13  |                           | 
    |	|     |     |     |     |     |                           | 
    |   +-----+     +-----+     +-----+                           | 
    |                                                             | 
    |   +-----+     +-----+     +-----+     +-----+     +-----+   | 
    |	| 6   |     | 7   |     | 8   |     | 9   |     | 10  |   |
    |	|     |     |     |     |     |     |     |     |     |   |
    |   +-----+     +-----+     +-----+     +-----+     +-----+   |
    |                                                             | 
    |   +-----+     +-----+     +-----+     +-----+     +-----+   | 
    |	| 1   |     | 2   |     | 3   |     | 4   |     | 5   |   |
    |	|     |     |     |     |     |     |     |     |     |   |
    |   +-----+     +-----+     +-----+     +-----+     +-----+   | 
    |                                                             | 
    +-------------------------------------------------------------+

That should be enough description of the widget.  Now, the problem...

There exists a widget instance initialization routine within the widget.  The
routine is called RectArrayInitialize.  It of course, receives to parameters:
the requested widget, and the new widget.  This routine is executed when
the Client application calls XtCreateWidget.

Based on my limited understanding of widgets, XtCreateWidget ought to take
the arglist passed to it, and place the resource values specified therein
into the requested widget which is passed to my initialization routine, 
RectArrayInitialize.  This, however is not happening.

Could someone please point me in the right direction?


The code is included in the replies to this note as follows:
                          
    .1		RectArray.c
    .2		RectArray.h
    .3		RectArrayP.h
    .4		RectArrayTest.c
    
T.RTitleUserPersonal
Name
DateLines
2452.1RectArray.cMDVAX3::WALTONThu Mar 15 1990 12:52427
/* 
** RectArray.C
*/

#include "RectArrayP.h"

#define RA_CHILDGAP(w)		((w)->rectArray.child_gap)
#define RA_CHILDWIDTH(w)	((w)->rectArray.child_width)
#define RA_CHILDHEIGHT(w)	((w)->rectArray.child_height)
#define RA_MARGINWIDTH(w)	((w)->rectArray.margin_width)
#define RA_FILLSTART(w)		((w)->rectArray.fill_start)
#define RA_FILLDIRECTION(w)	((w)->rectArray.fill_direction)
/*
** Macro do determine how many children will fit across a RectArray
** widget.
**
**  <----------------------------------------------------------------------->
**				    tw
**
**  +-----------------------------------------------------------------------+
**  |									    |
**  |									    |
**  |       +----------+          +----------+          +----------+	    |
**  |<----->|          |<-------->|<-------->|          |          |	    |
**  |  mw   |          |    wg    |    cw    |          |          |	    |
**  |       +----------+          +----------+          +----------+	    |
**  |									    |
**  +-----------------------------------------------------------------------+
**
**  tw = total width (f RectArray widget
**  cw = child width
**  mw = margin width
**  wg = widget gap (i.e. distance between children)
*/

#define CHILDRENACROSS(tw, cw, mw, wg)				\
    (								\
    tw < cw + (2 * mw) ?					\
	1 :							\
	((tw - 2 * mw - cw) / (cw + wg)) + 1			\
    )
	    
/*  
** Macro to calculate the actual gap between RectArray widget children.
**
**  tw	= total width (of RectArray widget)
**  nca = number of children across (the RectArray widget)
**  mw  = margin width
**  cw	= child width 
**
** returns (Total_Gap_Space / Number_Of_Gaps)
*/
#define CHILDGAP(tw, nca, mw, cw)				\
    (								\
    (tw - (2 * mw) - (nca * cw))  /  (nca - 1)			\
    )
        


/*
** Forward references to routines.
*/
static void		PlaceChild();
static void		Destroy();

static XtProc		RectArrayClassInitialize();
static XtInitProc	RectArrayInitialize();
static XtRealizeProc	RectArrayRealize();

/*
** Define resources.
*/
static XtResource resources[] =
    {
	{
	XtNmarginWidth,
	XtCValue,
	XtRShort,
	sizeof(Dimension),
	XtOffset(RectArrayWidget, rectArray.margin_width),
	XtRImmediate,
	5
	},
	{
	XtNchildGap,
	XtCValue,
	XtRShort,
	sizeof(Dimension),
	XtOffset(RectArrayWidget, rectArray.child_gap),
	XtRImmediate,
	5
	},
	{
	XtNchildWidth,
	XtCValue,
	XtRShort,
	sizeof(Dimension),
	XtOffset(RectArrayWidget, rectArray.child_width),
	XtRImmediate,
	10
	},
	{
	XtNchildHeight,
	XtCValue,
	XtRShort,
	sizeof(Dimension),
	XtOffset(RectArrayWidget, rectArray.child_height),
	XtRImmediate,
	10
	},
	{
	XtNfillStart,
	XtCValue,
	XtRShort,
	sizeof(Dimension),
	XtOffset(RectArrayWidget, rectArray.fill_start),
	XtRImmediate,
	RAStartLowerLeft
	},
	{
	XtNfillDirection,
	XtCValue,
	XtRShort,
	sizeof(Dimension),
	XtOffset(RectArrayWidget, rectArray.fill_direction),
	XtRImmediate,
	RADirectionUpDown
	}
    };

static RectArrayClassRec rectArrayClassRec = 
    {
	{			/* CORE CLASS PART */
	(WidgetClass) & constraintClassRec, /* superclass */
	"RectArray",			    /* class_name */
	sizeof(RectArrayPart),		    /* widget_size */
	(XtProc)RectArrayClassInitialize,   /* class_initialize */
	NULL,				    /* class_part_initialize*/
	FALSE,				    /* class_inited */
	(XtInitProc)RectArrayInitialize,    /* initialize */
	NULL,				    /* initialize_hook */
	(XtRealizeProc)RectArrayRealize,    /* realize */
	NULL,				    /* actions */
	NULL,				    /* num_actions */
	resources,			    /* resources */
	XtNumber(resources),		    /* num_resources */
	NULLQUARK,			    /* xrm_class */
	TRUE,				    /* compress_motion */
	TRUE,				    /* compress_exposure */
	TRUE,				    /* compress_enterleave*/
	FALSE,				    /* visible_interest */
	Destroy,			    /* destroy */
	XtInheritResize,		    /* resize */
	XtInheritExpose,		    /* expose */
	NULL,				    /* set_values */
	NULL,				    /* set_values_hook */
	XtInheritSetValuesAlmost,	    /* set_values_almost */
	NULL,				    /* get_values_hook */
	XtInheritAcceptFocus,		    /* accept_focus */
	XtVersionDontCheck,		    /* version */
	NULL,				    /* callback offsets */
	XtInheritTranslations,		    /* tm_table */
	XtInheritQueryGeometry,		    /* query geometry */
	XtInheritDisplayAccelerator,	    /* display accelerators */
	NULL				    /* extension */
	},
	{			/* COMPOSITE CLASS RECORD */
	XtInheritGeometryManager,	    /* children's geometry mgr. */
	XtInheritChangeManaged,		    /* set changed proc */
	XtInheritInsertChild,		    /* add a child */
	XtInheritDeleteChild,		    /* remove a child */
	NULL				    /* extension */
	},
	{			/* CONSTRAINT CLASS RECORD */
	NULL,				    /* constraint resources */
 	0,				    /* number of constraints in list */
	0,				    /* size of constraint record */
	NULL,				    /* constraint initialize */
	NULL,				    /* constraint destroy proc */
	NULL,				    /* constraint set values proc */
	NULL				    /* extension */
	},
	{			/* HOLDER CLASS RECORD */
	NULL				    /* reserved */
	}
    };

externaldef (RectArrayClassRec)
    WidgetClass rectArrayWidgetClass = (WidgetClass) &rectArrayClassRec;


/* 
** Class initialization routine
*/
static XtProc RectArrayClassInitialize()
    {
    printf("RectArray -- Initialize class\n");
    DwtResolvePartOffsets(
	rectArrayWidgetClass,
	&rectArrayClassRec.rectArray_class.rectarray_offsets);
    }

/*
** Instance initialization routine
*/
static XtInitProc RectArrayInitialize(
    RectArrayWidget request,
    RectArrayWidget new)
    {
    printf("RectArray -- Initialize instance\n");
    printf("    Requested child width:  %d\n", request->rectArray.child_width);

    if (request->rectArray.margin_width == 0)
	new->rectArray.margin_width = 3;
    if (request->rectArray.child_gap == 0)
	new->rectArray.child_gap = 5;
    if (request->rectArray.child_width == 0)
	new->rectArray.child_width = 40;
    if (request->rectArray.child_height== 0)
	new->rectArray.child_height = 27;
    }

/*
** Realize an instance of the widget.
**
** This involves creating the window for the RectArray widget, and specifying
** the initial layout of its children.
*/
static XtRealizeProc RectArrayRealize(
    RectArrayWidget w,
    Mask *valueMask,
    XSetWindowAttributes *attributes)
    {
    WidgetList	    child;	    /* pointer to a list of child widgets */
    Boolean	    newRow = TRUE;  /* flag */
    int		    i,		    /* loop counter */
		    numAcross,	    /* number of children across */
		    num,	    /* number of child widgets */
		    gap,	    /* size of gap between children */
		    rowCount,	    /* counter variable */
		    columnCount,    /* counter variable */
		    childX,	    /* x coordinate of a child */
		    childY;	    /* y coordinate of a child */

    printf("RectArray -- Realize widget\n");

    /*
    ** Create the window on the server.
    */
    XtCreateWindow(
	w,			/* Widget id */
	InputOutput,		/* Window class */
	CopyFromParent,		/* Visual */
	*valueMask,		/* Window attribute mask */
	attributes);		/* Window attributes */

    /*
    ** Determine number of children managed.
    */
    num = w->composite.num_children;

    /*
    ** Get the list of widgets managed by RectArray
    */
    child = w->composite.children;

    /*
    ** Determine how many children will fit across RectArray
    */
    numAcross = CHILDRENACROSS(
		    XtWidth(w),
		    w->rectArray.child_width,
		    w->rectArray.margin_width,
		    w->rectArray.child_gap);

    /*
    ** Adjust the child gap so the children will be spread more evenly.
    */
    gap = CHILDGAP(
	    XtWidth(w),
	    numAcross,
	    w->rectArray.margin_width,
	    w->rectArray.child_width);

    /*
    ** For all children
    */
    for (rowCount = columnCount = i = 0; i < num; i++)
	{
	/*
	** Set child's size.
	*/
	XtResizeWidget(
	    child[i],
	    RA_CHILDWIDTH(w),
	    RA_CHILDHEIGHT(w),
	    XtBorderWidth(child[i]));

	/*
	** Position the child.
	*/
	PlaceChild(
	    child[i],
	    w,
	    &newRow,
	    numAcross,
	    gap,
	    &rowCount,
	    &columnCount,
	    &childX,
	    &childY);

	XtMoveWidget(
	    child[i], 
	    (Position)childX, 
	    (Position)childY);
	}
    }

static void Destroy()
    {
    }

static void PlaceChild(
    Widget		cw,
    RectArrayWidget	w,
    Boolean		*newRow,
    int			numPerRow,
    int			gap,
    int			*row,
    int			*columnCount,
    int			*X,
    int			*Y)
    {

    (*columnCount)++;

    if (*newRow)
	{
	(*row)++;
	*X = RA_MARGINWIDTH(w);
	*newRow = FALSE;
	/*
	** Since it's a new row, we need to change the Y coordinate
	*/
	if (*row == 1)
	    {
	    if (RA_FILLSTART(w) == RAStartUpperLeft || 
		RA_FILLSTART(w) == RAStartUpperRight) 
		{
		*Y = RA_MARGINWIDTH(w);
		}
	    else
		{
		*Y = XtHeight(w) - RA_MARGINWIDTH(w) - RA_CHILDHEIGHT(w);
		}
	    }
	else
	    {
	    if (RA_FILLSTART(w) == RAStartUpperLeft || 
		RA_FILLSTART(w) == RAStartUpperRight) 
		{
		*Y += RA_CHILDGAP(w) + RA_CHILDHEIGHT(w);
		}
	    else
		{
		*Y -= RA_CHILDGAP(w) + RA_CHILDHEIGHT(w);
		}
	    }

	}
    else
	{
	*X += gap + RA_CHILDWIDTH(w);
	}

    if (*columnCount == numPerRow)
	{
	*columnCount = 0;
	*newRow = TRUE;
	}
    }


/*
** -------------------------------------------------------------------------
** RectArray Widget Interface Routines
** -------------------------------------------------------------------------
*/

/*
** Low-level creation routine for the RectArray widget.
*/
Widget RectArrayCreate(
    Widget  parent,
    String  name,
    Arg	    args,
    int	    num_args)
    {
    return  (XtCreateWidget(
		name,
		rectArrayWidgetClass,
		parent,
		args,
		num_args));
    }

/*
** Register the RectArray Class with the Resource Manager
*/
void RectArrayDRMInitialize()
{
    if( DwtRegisterClass (
	    DRMwcUnknown,		/* User defined widget	*/ 
	    "RectArrayClass",		/* class name		*/
	    "RectArrayCreate",		/* create routine name	*/
	    RectArrayCreate,		/* and its address	*/
	    rectArrayWidgetClass)	/* Pointer to class rec	*/
	!= DRMSuccess)
	{
	printf("RectArray -- Can't register RectArray widget\n");
	}
    else
	{
	printf("RectArray -- Widget successfully registered with DRM\n");
	}
    }
2452.2RectArray.hMDVAX3::WALTONThu Mar 15 1990 12:5640
/*
** RectArray.H
*/

#ifndef RECTARRAY_H
#define RECTARRAY_H

#ifdef VAXC
#define external globalref
#else
#define external extern
#endif

/*
** Constants
*/
#define	RAStartLowerLeft	    0
#define RAStartLowerRight	    1
#define RAStartUpperLeft	    2
#define RAStartUpperRight	    3

#define RADirectionUpDown	    0
#define RADirectionLeftRight	    1

/*
** Resource names
*/
#define XtNmarginWidth	    "marginWidth"
#define XtNchildGap	    "childGap"
#define XtNchildWidth	    "childWidth"
#define XtNchildHeight	    "childHeight"
#define XtNfillStart	    "fillStart"
#define XtNfillDirection    "fillDirection"


typedef struct _RectArrayClassRec *RectArrayWidgetClass;
external WidgetClass rectArrayWidgetClass;

void RectArrayDRMInitialize();
#endif RECTARRAY_H
2452.3RectArrayP.hMDVAX3::WALTONThu Mar 15 1990 12:5859
/* 
** RectArrayP.H
*/

#ifndef RECTARRAYP_H
#define RECTARRAYP_H

#ifdef VMS
#include <Decw$Include:DwtWidget.h>
#else
#include <X11/DwtWidget.h>
#endif

#include "RectArray.h"

/* definition of the class record */

typedef struct _RectArrayClass 
    {
    DwtOffsetPtr rectarray_offsets;
    int reserved;
    } RectArrayClassPart;

typedef struct _RectArrayClassRec 
    {
    CoreClassPart core_class;
    CompositeClassPart composite_class;
    ConstraintClassPart constraint_class;
    RectArrayClassPart rectArray_class;
    } RectArrayClassRec, *RectArrayClass;

/* definition of the instance record */

typedef struct _RectArrayPart 
    {
    Dimension	margin_width;
    Dimension	child_gap;
    Dimension	child_width;
    Dimension	child_height;
    /*
    ** Specifies which corner the RectArray widget should begin in when 
    ** placing its children.
    */
    int		fill_start;
    /*
    ** Specifies which direction the widget fill should start first.
    */
    int		fill_direction;
    } RectArrayPart;

typedef struct _RectArrayRec 
    {
    CorePart core;
    CompositePart   composite;
    ConstraintPart  constraint;
    RectArrayPart   rectArray;
    } RectArrayRec, *RectArrayWidget;

#endif RECTARRAYP_H
2452.4RectArrayTest.cMDVAX3::WALTONThu Mar 15 1990 13:1599
/* 
** RectArrayTest.C 
*/

#include <stdio.h>
#ifdef VMS
#include <Decw$Include/DwtAppl.h>
#else
#include <X11/DwtAppl.h>
#endif

#include "RectArray.h"

#define NUM_BUTTONS 15

static void exit_proc();

static DwtCallback exitCallback[2] = 
    {
	{exit_proc, NULL}, 
	{NULL, NULL}
    };

int main(
    unsigned int argc,
    char **argv)
    {
    Display *display;
    XtAppContext context;
    Widget topLevel, rectArrayWidget;
    Widget exitButton, button[NUM_BUTTONS];
    Arg arglist[5];
    int i;

    /*
    ** Initialize the Resource Manager.
    */
    DwtInitializeDRM();
    RectArrayDRMInitialize();

    /*
    ** Initialize the toolkit
    */
    XtToolkitInitialize();

    context = XtCreateApplicationContext();
    display =
      XtOpenDisplay(context, "", 
	"holdertest", 
	"Test", 
	NULL, 0, 
	&argc, argv);

    topLevel = XtAppCreateShell("RectArrayTest",
      "Test", 				
      applicationShellWidgetClass, display, arglist, 0);

    i = 0;
    XtSetArg(arglist[i], DwtNwidth, 250);   i++;
    XtSetArg(arglist[i], DwtNheight, 250);  i++;
    XtSetArg(arglist[i], XtNchildWidth, 60);  i++;

    rectArrayWidget = 
	XtCreateManagedWidget("rectArrayWidget",
      		(WidgetClass) rectArrayWidgetClass, 
		topLevel, 
		(ArgList) arglist, i);

    exitButton = DwtPushButton(rectArrayWidget, 
	"exitButton", 10, 10,
      	DwtLatin1String("Exit"), 
	exitCallback, NULL);

    XtManageChild(exitButton);

    for (i = 0; i < NUM_BUTTONS; i++)
	{
        char *label="Button     ";

	sprintf (label, "%d\0", i);

	button[i] = DwtPushButton(rectArrayWidget, "Button2", 
	    100, 100,
	    DwtLatin1String(label), 
	    NULL, NULL);

	XtManageChild(button[i]);
	}

    XtRealizeWidget(topLevel);

    XtAppMainLoop(context);
}

static void exit_proc()
{
    exit();
}

2452.5Use DwtPartOffset ; not XtOffsetLEOVAX::TREGGIARIThu Mar 15 1990 14:3316
Look at the documentation of DwtResolvePartOffsets again.  You are missing one
of the steps.  You should be using DwtPartOffset instead of XtOffset.

For example, instead of

	XtOffset(RectArrayWidget, rectArray.child_height),

Use

	DwtPartOffset(RectArray, child_height);

You also need (and may already have; I didn't search your code...)

#define RectArrayIndex (DwtConstraintIndex + 1)

Leo
2452.6Quick fixDECWIN::KLEINThu Mar 15 1990 14:3417
I'm not sure I can give a cogent explanation of what you were doing
wrong, since I'm not into subclassing the way you seem to be, but I
got your widget to work by making the following two-line change:

************
File WORK1:[KLEIN.CODE]RECTARRAY.C;2
  136           sizeof(RectArrayRec),               /* widget_size */
  137           NULL,                               /* class_initialize */
******
File WORK1:[KLEIN.CODE]RECTARRAY.C;1
  143           sizeof(RectArrayPart),              /* widget_size */
  144           (XtProc)RectArrayClassInitialize,   /* class_initialize */
************

(Nice widget.)

-steve-