/* $XConsortium: xmform.c /main/4 1995/07/15 20:47:50 drk $ */
/*
 *  @OPENGROUP_COPYRIGHT@
 *  COPYRIGHT NOTICE
 *  Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
 *  Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group
 *  ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
 *  the full copyright text.
 *  
 *  This software is subject to an open license. It may only be
 *  used on, with or for operating systems which are themselves open
 *  source systems. You must contact The Open Group for a license
 *  allowing distribution and sublicensing of this software on, with,
 *  or for operating systems which are not Open Source programs.
 *  
 *  See http://www.opengroup.org/openmotif/license for full
 *  details of the license agreement. Any use, reproduction, or
 *  distribution of the program constitutes recipient's acceptance of
 *  this agreement.
 *  
 *  EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
 *  PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
 *  WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
 *  OR FITNESS FOR A PARTICULAR PURPOSE
 *  
 *  EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
 *  NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT,
 *  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 *  DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED
 *  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
 *  EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGES.
 */
/*
 * HISTORY
 */
/**---------------------------------------------------------------------
***	
***	file:		xmform.c
***
***	project:	Motif Widgets example programs
***
***	creation:	Spring 91 - Cambridge
***                       Daniel Dardailler.
***
***	description:	This program demonstrates the possibilities of
***                     the Motif form widget.
***                     It can display a string of letters made from buttons 
***	                and arrows (resizable using Form attachments).
***
***	defaults:	xmform looks nicer with these defaults:
***
xmform*highlightThickness:       0
xmform.XmForm.shadowThickness:   3
xmform*XmPushButton.background:  cadetblue
xmform*XmArrowButton.foreground: cadetblue
xmform*XmArrowButton.background: lightgrey
xmform*XmForm.background:        lightgrey
xmform*topShadowColor:           white
xmform*bottomShadowColor:        black
***-------------------------------------------------------------------*/

#include <Xm/Xm.h>
#include <Xm/Form.h>
#include <Xm/PushB.h>
#include <Xm/ArrowB.h>

static void FillItPlease();
static void NearlyEvenSpread();
static Widget AddStem() ;

int main(argc, argv) 
int argc; char **argv;
{
    XtAppContext app_context;
    Widget      toplevel, topform, *forms ;
    Cardinal len_word, p ;
    String word = "MOTIF" ;
    char s[2] ;

    toplevel = XtAppInitialize(&app_context, "XMdemos", NULL, 0,
			       &argc, argv, NULL, NULL, 0);
    topform = XmCreateForm(toplevel, "topform", NULL, 0);
    XtManageChild(topform);

    /* pick up the string to be displayed if any */
    if (argc == 2) word = argv[1] ;

    /* create a form for each letter and fill it with the 'stem widgets' */
    len_word = strlen(word);
    forms = (Widget*)calloc(len_word,sizeof(Widget));
    s[1] = 0 ;  /* string used for the subform widget name */
    for (p = 0 ; p < len_word; p++) { 
	s[0] = word[p] ;  /* subform  names are the letters themselves */
	forms[p] = XmCreateForm(topform, s, NULL, 0); 
	FillItPlease(forms[p], word[p]);
    }

    /* evenly spread out the forms with some spacing in between */
    NearlyEvenSpread(forms, p, 
		     2,          /* horizontal spacing */
		     9) ;        /* vertical margin */

    XtManageChildren(forms, p);
    XtRealizeWidget(toplevel);
    XtAppMainLoop(app_context);

    return 0;    /* make compiler happy */
}


static void NearlyEvenSpread(child_list, num_child, 
			     hor_spacing, ver_spacing)
Widget * child_list;
Cardinal num_child;
Dimension hor_spacing;
Dimension ver_spacing;
{
    /* this algorithm works only for the default fractionBase == 100 */
    /* hor_spacing and ver_margin are equally applied on each sides */

    Dimension hor_child_room ;
    Cardinal n, i ;
    Arg args[10] ;

    hor_child_room = 100 / num_child ;

    for (i = 0 ; i < num_child ; i++) {
	n = 0 ;
	XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++ ;
	XtSetArg(args[n], XmNleftPosition, 
		 hor_child_room*i + hor_spacing); n++ ;
	XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++ ;
	XtSetArg(args[n], XmNrightPosition, 
		 hor_child_room*(i+1) - hor_spacing); n++ ;
	XtSetArg(args[n], XmNtopAttachment, XmATTACH_POSITION); n++ ;
	XtSetArg(args[n], XmNtopPosition, ver_spacing); n++ ;
	XtSetArg(args[n], XmNbottomAttachment, XmATTACH_POSITION); n++ ;
	XtSetArg(args[n], XmNbottomPosition, 100 - ver_spacing); n++ ;
	XtSetValues(child_list[i], args, n);
    }
}

static void FillItPlease(form, letter)
Widget form ;
char letter ;
{
    /* This routine only handle the "MOTIF" letters, it's up 
       to you to implement the rest, good luck for K,N,R,V,X,Y,Z... */

    Cardinal n = 0, p = 0 ;
    Arg args[10] ;
    Widget child[10] ;

    switch(letter) {
    case 'M' :
	/* 2 buttons and the arrow in between on top */
	child[p] = AddStem(form, 0, 25, 100, 0, XmPUSHBUTTON); p++;
	child[p] = AddStem(form, 0, 100, 100, 75, XmPUSHBUTTON); p++;
	child[p] = AddStem(form, 0, 75, 35, 25, NULL); p++;
/*	XtSetArg(args[n], XmNshadowThickness, 0); n++;*/
	XtSetArg(args[n], XmNarrowDirection, XmARROW_DOWN); n++;
	XtSetValues(child[2], args, n);
	XtManageChildren(child, p);
	break ;
    case 'O' :
	/* 2 left and right vertical buttons and 2 horizontals */
	child[p] = AddStem(form, 25, 25, 75, 0, XmPUSHBUTTON); p++;
	child[p] = AddStem(form, 0, 100, 25, 0, XmPUSHBUTTON); p++;
	child[p] = AddStem(form, 25, 100, 75, 75, XmPUSHBUTTON); p++;
	child[p] = AddStem(form, 75, 100, 100, 0, XmPUSHBUTTON); p++;
	XtManageChildren(child, p);
	break ;
    case 'T' :
	/* 1 vertical button and 1 horizontal on top */
	child[p] = AddStem(form, 25, 63, 100, 38, XmPUSHBUTTON); p++;
	child[p] = AddStem(form, 0, 100, 25, 0, XmPUSHBUTTON); p++;
	XtManageChildren(child, p);
	break ;
    case 'I' :
	/* 1 vertical button + one arrow on top */
	child[p] = AddStem(form, 0, 63, 25, 38, NULL); p++;
	child[p] = AddStem(form, 30, 63, 100, 38, XmPUSHBUTTON); p++;
/*	XtSetArg(args[n], XmNshadowThickness, 0); n++;*/
	XtSetValues(child[0], args, n);
	XtManageChildren(child, p);
	break ;
    case 'F' :
	/* 1 vertical button and 2 horizontal on the right */
	child[p] = AddStem(form, 0, 25, 100, 0, XmPUSHBUTTON); p++;
	child[p] = AddStem(form, 0, 100, 25, 25, XmPUSHBUTTON); p++;
	child[p] = AddStem(form, 36, 75, 61, 25, XmPUSHBUTTON); p++;
	XtManageChildren(child, p);
	break ;
    default:
	child[p] = AddStem(form, 0, 100, 100, 0, XmPUSHBUTTON); p++;
	XtManageChildren(child, p);
	break ;
    }
}


static Widget AddStem(form, top, right, bottom, left, type)
Widget form ;
Dimension top, right, bottom, left;
int type ;
{
    /* create an object, either a button or an arrow, using
       positionnal attachment everywhere, instead of possibly 
       form attachment or widget attachment */

    Cardinal n = 0 ;
    Arg args[10] ;

    XtSetArg(args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
    XtSetArg(args[n], XmNtopPosition, top); n++;
    XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
    XtSetArg(args[n], XmNrightPosition, right); n++;
    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
    XtSetArg(args[n], XmNbottomPosition, bottom); n++;
    XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
    XtSetArg(args[n], XmNleftPosition, left); n++;
    if (type == XmPUSHBUTTON)
	return XmCreatePushButton(form, "", args, n); 
    else 
	return XmCreateArrowButton(form, "", args, n); 
}

