Blame lib/Xm/RCLayout.c

Packit b099d7
/*
Packit b099d7
 * Motif
Packit b099d7
 *
Packit b099d7
 * Copyright (c) 1987-2012, The Open Group. All rights reserved.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are free software; you can
Packit b099d7
 * redistribute them and/or modify them under the terms of the GNU
Packit b099d7
 * Lesser General Public License as published by the Free Software
Packit b099d7
 * Foundation; either version 2 of the License, or (at your option)
Packit b099d7
 * any later version.
Packit b099d7
 *
Packit b099d7
 * These libraries and programs are distributed in the hope that
Packit b099d7
 * they will be useful, but WITHOUT ANY WARRANTY; without even the
Packit b099d7
 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
Packit b099d7
 * PURPOSE. See the GNU Lesser General Public License for more
Packit b099d7
 * details.
Packit b099d7
 *
Packit b099d7
 * You should have received a copy of the GNU Lesser General Public
Packit b099d7
 * License along with these librararies and programs; if not, write
Packit b099d7
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
Packit b099d7
 * Floor, Boston, MA 02110-1301 USA
Packit b099d7
 */
Packit b099d7
/*
Packit b099d7
 * HISTORY
Packit b099d7
 */
Packit b099d7
Packit b099d7
#ifdef HAVE_CONFIG_H
Packit b099d7
#include <config.h>
Packit b099d7
#endif
Packit b099d7
Packit b099d7
Packit b099d7
#ifdef REV_INFO
Packit b099d7
#ifndef lint
Packit b099d7
static char *rcsid = "$XConsortium: RCLayout.c /main/6 1995/10/25 20:14:15 cde-sun $";
Packit b099d7
#endif
Packit b099d7
#endif
Packit b099d7
Packit b099d7
#include <stdio.h>
Packit b099d7
#include <ctype.h>
Packit b099d7
#ifndef X_NOT_STDC_ENV
Packit b099d7
#include <stdlib.h>
Packit b099d7
#endif
Packit b099d7
#include <Xm/CascadeBGP.h>
Packit b099d7
#include <Xm/CascadeBP.h>
Packit b099d7
#include <Xm/GadgetP.h>
Packit b099d7
#include <Xm/LabelP.h>
Packit b099d7
#include <Xm/ManagerP.h>
Packit b099d7
#include <Xm/PrimitiveP.h>
Packit b099d7
#include <Xm/RowColumnP.h>
Packit b099d7
#include <Xm/TearOffBP.h>
Packit b099d7
#include <Xm/TearOffP.h>
Packit b099d7
#include <Xm/XmosP.h>		/* for bzero */
Packit b099d7
#include "LabelGI.h"
Packit b099d7
#include "GeoUtilsI.h"
Packit b099d7
#include "RCLayoutI.h"
Packit b099d7
#include "RowColumnI.h"
Packit b099d7
#include "XmI.h"
Packit b099d7
Packit b099d7
#define RESOURCE_MIN_WIDTH	16 /* 'cuz it's the size of a hot spot... */
Packit b099d7
#define RESOURCE_MIN_HEIGHT	16
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
static void CalcHelp( 
Packit b099d7
                        XmRowColumnWidget m,
Packit b099d7
                        Dimension *m_width,
Packit b099d7
                        Dimension *m_height,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int b,
Packit b099d7
                        int max_x,
Packit b099d7
                        int max_y,
Packit b099d7
#else
Packit b099d7
                        Dimension b,
Packit b099d7
                        Position max_x,
Packit b099d7
                        Position max_y,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
                        Position *x,
Packit b099d7
                        Position *y,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int w,
Packit b099d7
                        int h) ;
Packit b099d7
#else
Packit b099d7
                        Dimension w,
Packit b099d7
                        Dimension h) ;
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
Packit b099d7
static void GetMaxValues( 
Packit b099d7
                        XmRowColumnWidget m,
Packit b099d7
                        Dimension *border,
Packit b099d7
                        Dimension *w,
Packit b099d7
                        Dimension *h,
Packit b099d7
                        int *items_per,
Packit b099d7
                        Dimension *baseline,
Packit b099d7
                        Dimension *shadow,
Packit b099d7
                        Dimension *highlight,
Packit b099d7
                        Dimension *margin_top,
Packit b099d7
                        Dimension *margin_height,
Packit b099d7
                        Dimension *text_height) ;
Packit b099d7
Packit b099d7
static void AdjustLast( 
Packit b099d7
                        XmRowColumnWidget m,
Packit b099d7
                        int start_i,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int w,
Packit b099d7
                        int h) ;
Packit b099d7
#else
Packit b099d7
                        Dimension w,
Packit b099d7
                        Dimension h) ;
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
static void SetAsking( 
Packit b099d7
                        XmRowColumnWidget m,
Packit b099d7
                        Dimension *m_width,
Packit b099d7
                        Dimension *m_height,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int b,
Packit b099d7
                        int max_x,
Packit b099d7
                        int max_y,
Packit b099d7
                        int x,
Packit b099d7
                        int y,
Packit b099d7
                        int w,
Packit b099d7
                        int h) ;
Packit b099d7
#else
Packit b099d7
                        Dimension b,
Packit b099d7
                        Position max_x,
Packit b099d7
                        Position max_y,
Packit b099d7
                        Position x,
Packit b099d7
                        Position y,
Packit b099d7
                        Dimension w,
Packit b099d7
                        Dimension h) ;
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
static void FindLargestOption( 
Packit b099d7
                        XmRowColumnWidget submenu,
Packit b099d7
                        Dimension *c_width,
Packit b099d7
                        Dimension *c_height) ;
Packit b099d7
static void TopOrBottomAlignment( 
Packit b099d7
                        XmRowColumnWidget m,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int h,
Packit b099d7
                        int shadow,
Packit b099d7
                        int highlight,
Packit b099d7
                        int baseline,
Packit b099d7
                        int margin_top,
Packit b099d7
                        int margin_height,
Packit b099d7
                        int text_height,
Packit b099d7
#else
Packit b099d7
                        Dimension h,
Packit b099d7
                        Dimension shadow,
Packit b099d7
                        Dimension highlight,
Packit b099d7
                        Dimension baseline,
Packit b099d7
                        Dimension margin_top,
Packit b099d7
                        Dimension margin_height,
Packit b099d7
                        Dimension text_height,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
                        Dimension *new_height,
Packit b099d7
                        int start_i,
Packit b099d7
                        int end_i) ;
Packit b099d7
static void BaselineAlignment( 
Packit b099d7
                        XmRowColumnWidget m,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int h,
Packit b099d7
                        int shadow,
Packit b099d7
                        int highlight,
Packit b099d7
                        int baseline,
Packit b099d7
#else
Packit b099d7
                        Dimension h,
Packit b099d7
                        Dimension shadow,
Packit b099d7
                        Dimension highlight,
Packit b099d7
                        Dimension baseline,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
                        Dimension *new_height,
Packit b099d7
                        int start_i,
Packit b099d7
                        int end_i) ;
Packit b099d7
static void CenterAlignment( 
Packit b099d7
                        XmRowColumnWidget m,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int h,
Packit b099d7
#else
Packit b099d7
                        Dimension h,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
                        int start_i,
Packit b099d7
                        int end_i) ;
Packit b099d7
static void ComputeTearOffHeight(
Packit b099d7
			XmRowColumnWidget m,
Packit b099d7
			Dimension *toc_b, 
Packit b099d7
                        Dimension *b, 
Packit b099d7
	                Dimension *toc_height,
Packit b099d7
                        int *start_i, 
Packit b099d7
                        int *child_i,
Packit b099d7
			int r);
Packit b099d7
static void LayoutColumn( 
Packit b099d7
                        XmRowColumnWidget m,
Packit b099d7
                        Dimension *m_width,
Packit b099d7
                        Dimension *m_height) ;
Packit b099d7
static void LayoutVerticalTight( 
Packit b099d7
                        XmRowColumnWidget m,
Packit b099d7
                        Dimension *m_width,
Packit b099d7
                        Dimension *m_height) ;
Packit b099d7
static void LayoutHorizontaltight( 
Packit b099d7
                        XmRowColumnWidget m,
Packit b099d7
                        Dimension *m_width,
Packit b099d7
                        Dimension *m_height) ;
Packit b099d7
static void LayoutNone( 
Packit b099d7
                        XmRowColumnWidget m,
Packit b099d7
                        Dimension *m_width,
Packit b099d7
                        Dimension *m_height) ;
Packit b099d7
static void LayoutOptionAndSize( 
Packit b099d7
                        register XmRowColumnWidget menu,
Packit b099d7
                        Dimension *width,
Packit b099d7
                        Dimension *height,
Packit b099d7
                        Widget instigator,
Packit b099d7
                        XtWidgetGeometry *request,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
                        int calcMenuDimension) ;
Packit b099d7
#else
Packit b099d7
                        Boolean calcMenuDimension) ;
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
static void GetMenuKidMargins(
Packit b099d7
				 XmRowColumnWidget m,
Packit b099d7
				 Dimension *width,
Packit b099d7
				 Dimension *height,
Packit b099d7
				 Dimension *left,
Packit b099d7
				 Dimension *right,
Packit b099d7
				 Dimension *top,
Packit b099d7
				 Dimension *bottom );
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*************************************************************************
Packit b099d7
 * 
Packit b099d7
 * This section is all the layout stuff, the whole thing has to operate 
Packit b099d7
 * in two different modes, one: a read-only mode which
Packit b099d7
 * is nice for making decisions about the size of the row column vs. the size
Packit b099d7
 * of the children.  two: a change everything mode which implements the
Packit b099d7
 * change.
Packit b099d7
 *
Packit b099d7
 * further complicated by the xtoolkit restriction that a subwidget making
Packit b099d7
 * a geo request (referred to as the 'instigator') of the row column may not 
Packit b099d7
 * have his resize proc called but all other widget children must.
Packit b099d7
 *
Packit b099d7
 * this is done by building a set of XtWidgetGeometry request blocks, one
Packit b099d7
 * for each child (widget and gadget), which holds the changes we would like  
Packit b099d7
 * to make for this child.  If needed then another pass is made over the  
Packit b099d7
 * requests to actually implement the changes.
Packit b099d7
 *************************************************************************/
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Decide where to put the help child.  He better be the last one
Packit b099d7
 * 'cuz we may trash the x, y's
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
CalcHelp(
Packit b099d7
        XmRowColumnWidget m,
Packit b099d7
        Dimension *m_width,     /* if 0 then caller's asking */
Packit b099d7
        Dimension *m_height,    /* if 0 then caller's asking */
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int b,
Packit b099d7
        int max_x,
Packit b099d7
        int max_y,
Packit b099d7
#else
Packit b099d7
        Dimension b,
Packit b099d7
        Position max_x,
Packit b099d7
        Position max_y,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        Position *x,
Packit b099d7
        Position *y,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int w,
Packit b099d7
        int h )
Packit b099d7
#else
Packit b099d7
        Dimension w,
Packit b099d7
        Dimension h )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
   register Dimension subtrahend;
Packit b099d7
Packit b099d7
   if (IsVertical (m))             /* glue to bottom edge of ... */
Packit b099d7
   {
Packit b099d7
      if (Asking (*m_height))
Packit b099d7
      {
Packit b099d7
	 if (RC_NCol (m) == 1)       /* just use max_y */
Packit b099d7
	     *y = max_y;
Packit b099d7
	 else                /* go up from max_y */
Packit b099d7
	 {
Packit b099d7
	     subtrahend = RC_Spacing (m) + h + b;
Packit b099d7
	     *y = (max_y > (int)subtrahend) ? max_y - subtrahend : 0; 
Packit b099d7
	 }
Packit b099d7
      }
Packit b099d7
      else
Packit b099d7
      {   
Packit b099d7
	  subtrahend = MGR_ShadowThickness(m) + RC_MarginH (m) + h + b;
Packit b099d7
	  *y = (*m_height > (int)subtrahend) ? *m_height - subtrahend : 0;
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
   else                    /* glue to right edge of ... */
Packit b099d7
   {
Packit b099d7
      if (Asking (*m_width))
Packit b099d7
      {
Packit b099d7
	 if (RC_NCol (m) == 1)
Packit b099d7
	     *x = max_x;
Packit b099d7
	 else
Packit b099d7
	 {
Packit b099d7
	     subtrahend = RC_Spacing (m) + w + b;
Packit b099d7
	     *x = (max_x > (int)subtrahend) ? max_x - subtrahend : 0;
Packit b099d7
	 }
Packit b099d7
      }
Packit b099d7
      else
Packit b099d7
      {
Packit b099d7
	 subtrahend = MGR_ShadowThickness(m) + RC_MarginW (m) + w + b;
Packit b099d7
	 *x = (*m_width > (int)subtrahend) ? *m_width - subtrahend : 0;
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * count the widest & tallest entry dimensions
Packit b099d7
 * and compute entries per row/column
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
GetMaxValues(
Packit b099d7
        XmRowColumnWidget m,
Packit b099d7
        Dimension *border,
Packit b099d7
        Dimension *w,
Packit b099d7
        Dimension *h,
Packit b099d7
        int *items_per,
Packit b099d7
        Dimension *baseline,
Packit b099d7
        Dimension *shadow,
Packit b099d7
        Dimension *highlight,
Packit b099d7
        Dimension *margin_top,
Packit b099d7
        Dimension *margin_height,
Packit b099d7
        Dimension *text_height )
Packit b099d7
{
Packit b099d7
    XtWidgetGeometry *b;
Packit b099d7
    Widget k ;
Packit b099d7
    int i, n ;
Packit b099d7
Packit b099d7
    *border = *w = *h = *baseline = *shadow = *highlight = 
Packit b099d7
	*margin_top = *margin_height = *text_height = 0;
Packit b099d7
Packit b099d7
    /* skip the tearoff control */
Packit b099d7
    for (i = (RC_TearOffControl(m) && 
Packit b099d7
	      XtIsManaged(RC_TearOffControl(m)))? 1 : 0, n = 0; 
Packit b099d7
	 RC_Boxes (m) [i].kid != NULL; 
Packit b099d7
	 i++, n++) {
Packit b099d7
       b = &(RC_Boxes (m) [i].box);
Packit b099d7
       k = RC_Boxes (m) [i].kid ;
Packit b099d7
       
Packit b099d7
       ASSIGN_MAX(*w, BWidth (b));
Packit b099d7
       ASSIGN_MAX(*h, BHeight (b));
Packit b099d7
Packit b099d7
       if (XtIsWidget(k)) {
Packit b099d7
	   ASSIGN_MAX(*border, k->core.border_width);
Packit b099d7
       } else if (XmIsGadget(k)) {
Packit b099d7
	   ASSIGN_MAX(*border, ((XmGadget)k)->rectangle.border_width);
Packit b099d7
       }
Packit b099d7
Packit b099d7
       ASSIGN_MAX(*baseline, RC_Boxes (m) [i].baseline);
Packit b099d7
         
Packit b099d7
       if (XmIsGadget (k) || XmIsPrimitive (k) ) {
Packit b099d7
         XmBaselineMargins textMargins;
Packit b099d7
	 _XmRC_SetOrGetTextMargins(k, XmBASELINE_GET, &textMargins);
Packit b099d7
         ASSIGN_MAX(*shadow, textMargins.shadow);
Packit b099d7
         ASSIGN_MAX(*highlight, textMargins.shadow);
Packit b099d7
         ASSIGN_MAX(*margin_top, textMargins.margin_top);
Packit b099d7
         ASSIGN_MAX(*margin_height, textMargins.margin_height);
Packit b099d7
         ASSIGN_MAX(*text_height, textMargins.text_height);
Packit b099d7
       }
Packit b099d7
    }
Packit b099d7
Packit b099d7
    *items_per = n / RC_NCol (m);       /* calc column size */
Packit b099d7
    if ((n % RC_NCol (m)) != 0) (*items_per)++;  /* some left overs */
Packit b099d7
                                                 /* add another row/col */
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * Make sure that entries in the right most column/row extend all the 
Packit b099d7
 * way to the right/bottom edge of the row column widget.  This keeps 
Packit b099d7
 * 'dead space' in the row column widget to a minimum.  For single 
Packit b099d7
 * column widgets, the only column is the right most.  
Packit b099d7
 *
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
AdjustLast(
Packit b099d7
        XmRowColumnWidget m,
Packit b099d7
        int start_i,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int w,
Packit b099d7
        int h )
Packit b099d7
#else
Packit b099d7
        Dimension w,
Packit b099d7
        Dimension h )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
   XmRCKidGeometry kg = RC_Boxes (m);
Packit b099d7
   XtWidgetGeometry *b;
Packit b099d7
   register Dimension subtrahend;
Packit b099d7
Packit b099d7
   for ( ; kg [start_i].kid != NULL; start_i++)
Packit b099d7
   {
Packit b099d7
      b = &(kg[start_i].box);
Packit b099d7
Packit b099d7
      if (IsVertical (m))
Packit b099d7
      {
Packit b099d7
         subtrahend = MGR_ShadowThickness(m) + RC_MarginW (m) + BX (b)
Packit b099d7
	     + Double (BBorder (b));
Packit b099d7
Packit b099d7
	 /* if w (rowcol width) is greater than subtrahend (the smallest
Packit b099d7
	  * width of the child, we'll guarantee at least a width of 1.
Packit b099d7
	  */
Packit b099d7
	 if (w > subtrahend) 
Packit b099d7
	     BWidth (b) = w-subtrahend;
Packit b099d7
      }
Packit b099d7
      else
Packit b099d7
      {
Packit b099d7
         subtrahend =  MGR_ShadowThickness(m) + RC_MarginH (m) + BY (b)
Packit b099d7
	     + Double (BBorder (b));
Packit b099d7
Packit b099d7
         /* When adjusting the last line, text and label widgets or gadgets, */
Packit b099d7
         /* use the extra height that is added differently. Text just adds  */
Packit b099d7
         /* it on whereas label tries to center it in the extra space.      */
Packit b099d7
         /* In order to make the baselines align again as a result of the   */
Packit b099d7
         /* above behavior,  Text's margin top has to be adjusted. */
Packit b099d7
	 if (h > subtrahend) 
Packit b099d7
         {
Packit b099d7
             Dimension m_top;
Packit b099d7
Packit b099d7
	     /* Check for underflow */
Packit b099d7
	     /* The difference is what it grows in height */
Packit b099d7
	     m_top = ((h-subtrahend) > BHeight(b)) ?
Packit b099d7
		((h-subtrahend) - BHeight (b)) : 0 ;
Packit b099d7
Packit b099d7
	     BHeight (b) = h-subtrahend;
Packit b099d7
         
Packit b099d7
	     if (m_top && (XmIsText(kg [start_i].kid) || 
Packit b099d7
			   XmIsTextField(kg [start_i].kid) ||
Packit b099d7
			   XmIsCSText(kg [start_i].kid)))
Packit b099d7
             {
Packit b099d7
	       kg [start_i].margin_top += m_top/2; /* Since labels center it */
Packit b099d7
             }
Packit b099d7
         }
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * decide exactly the dimensions of the row column widget we will return to 
Packit b099d7
 * an asking caller based on the accumulated layout information.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
SetAsking(
Packit b099d7
        XmRowColumnWidget m,
Packit b099d7
        Dimension *m_width,     /* if 0 then caller's asking */
Packit b099d7
        Dimension *m_height,    /* if 0 then caller's asking */
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int b,
Packit b099d7
        int max_x,
Packit b099d7
        int max_y,
Packit b099d7
        int x,
Packit b099d7
        int y,
Packit b099d7
        int w,
Packit b099d7
        int h )
Packit b099d7
#else
Packit b099d7
        Dimension b,
Packit b099d7
        Position max_x,
Packit b099d7
        Position max_y,
Packit b099d7
        Position x,
Packit b099d7
        Position y,
Packit b099d7
        Dimension w,
Packit b099d7
        Dimension h )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
    long iheight;
Packit b099d7
    long iwidth;
Packit b099d7
Packit b099d7
    if (IsVertical (m))             /* tell caller what he wants */
Packit b099d7
    {
Packit b099d7
        if (Asking (*m_width))
Packit b099d7
            *m_width =   x + w + b      /* right edge of last child */
Packit b099d7
                   + MGR_ShadowThickness(m)
Packit b099d7
                   + RC_MarginW (m);    /* plus margin on right */
Packit b099d7
Packit b099d7
        if (Asking (*m_height))
Packit b099d7
        {
Packit b099d7
            ASSIGN_MAX (max_y, y);
Packit b099d7
Packit b099d7
            iheight = (long) max_y                /* last unused y */
Packit b099d7
                - (long) (RC_Spacing (m))         /* up by unused spacing */
Packit b099d7
                + (long) (MGR_ShadowThickness(m))
Packit b099d7
                + (long) (RC_MarginH (m)) ;       /* plus margin on bottom */
Packit b099d7
Packit b099d7
            if (iheight < 0)             /* this is a temporary fix */
Packit b099d7
                *m_height = 0;           /* to make sure we don't   */
Packit b099d7
            else                         /* compute a negative height */
Packit b099d7
                *m_height = (Dimension) iheight; /*in an unsigned short   */
Packit b099d7
        }
Packit b099d7
    }
Packit b099d7
    else
Packit b099d7
    {
Packit b099d7
        if (Asking (*m_width))
Packit b099d7
        {
Packit b099d7
            ASSIGN_MAX (max_x, x);
Packit b099d7
Packit b099d7
            iwidth = (long) max_x
Packit b099d7
                - (long) (RC_Spacing (m))
Packit b099d7
                + (long) (MGR_ShadowThickness(m))
Packit b099d7
                + (long) (RC_MarginW (m)) ;
Packit b099d7
Packit b099d7
            if (iwidth < 0)
Packit b099d7
                *m_width = 0;
Packit b099d7
            else
Packit b099d7
                *m_width = (Dimension) iwidth ;
Packit b099d7
        }
Packit b099d7
Packit b099d7
        if (Asking (*m_height))
Packit b099d7
            *m_height = y + h + b
Packit b099d7
                + MGR_ShadowThickness(m)
Packit b099d7
                + RC_MarginH (m);
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
Packit b099d7
static void
Packit b099d7
FindLargestOption( 
Packit b099d7
	XmRowColumnWidget submenu, 
Packit b099d7
	Dimension *c_width, 
Packit b099d7
	Dimension *c_height )
Packit b099d7
{
Packit b099d7
    int i;
Packit b099d7
    Widget *child ;
Packit b099d7
Packit b099d7
    if (!submenu) return ;
Packit b099d7
    
Packit b099d7
    ForManagedChildren (submenu, i, child) {
Packit b099d7
	/* Is this recursivity wanted ? */
Packit b099d7
	if (XmIsCascadeButton(*child))	{
Packit b099d7
	    FindLargestOption((XmRowColumnWidget)
Packit b099d7
			      CB_Submenu(*child), 
Packit b099d7
			      c_width, c_height);
Packit b099d7
	}
Packit b099d7
	else if (XmIsCascadeButtonGadget(*child))	       {
Packit b099d7
	    FindLargestOption((XmRowColumnWidget)
Packit b099d7
			      CBG_Submenu(*child), 
Packit b099d7
			      c_width, c_height);
Packit b099d7
	}
Packit b099d7
	else {
Packit b099d7
	    /* The entire size of the largest menu
Packit b099d7
	     * item is used instead of only its TextRect.  This may
Packit b099d7
	     * result in large expanses of label white space when items 
Packit b099d7
	     * utilize left and right margins, shadow, or accelerator 
Packit b099d7
	     * text - but the glyph will be visible when the submenu is
Packit b099d7
	     * posted!
Packit b099d7
	     */
Packit b099d7
	    if (XmIsMenuShell(XtParent(submenu))) {
Packit b099d7
		ASSIGN_MAX(*c_width, XtWidth(*child));
Packit b099d7
		ASSIGN_MAX(*c_height, XtHeight(*child));
Packit b099d7
	    }
Packit b099d7
	    
Packit b099d7
	    /*
Packit b099d7
	     * must be a torn pane.  Don't rely on its dimensions
Packit b099d7
	     * since it may be stretched in the tear off so that
Packit b099d7
	     * the label string fits into the titlebar
Packit b099d7
	     */
Packit b099d7
	    else {
Packit b099d7
		XtWidgetGeometry preferred;
Packit b099d7
		
Packit b099d7
		XtQueryGeometry (*child, NULL, &preferred);
Packit b099d7
		ASSIGN_MAX(*c_width, preferred.width);
Packit b099d7
		ASSIGN_MAX(*c_height, preferred.height);
Packit b099d7
		
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
void
Packit b099d7
_XmRC_CheckAndSetOptionCascade(
Packit b099d7
      XmRowColumnWidget menu )
Packit b099d7
{
Packit b099d7
   Dimension width = 0;
Packit b099d7
   Dimension height = 0;
Packit b099d7
   int i;
Packit b099d7
   Widget cb;
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * if its is a pulldown menu, travel up the cascades to verify the
Packit b099d7
    * option menus cascade button is sized large enough.  
Packit b099d7
    */
Packit b099d7
   if (IsPulldown(menu)) {
Packit b099d7
       for (i=0; i < menu->row_column.postFromCount; i++) {
Packit b099d7
	   _XmRC_CheckAndSetOptionCascade((XmRowColumnWidget)
Packit b099d7
				XtParent(menu->row_column.postFromList[i]));
Packit b099d7
       }
Packit b099d7
   } 
Packit b099d7
Packit b099d7
   if (!IsOption(menu)  || RC_FromResize(menu)) return ;
Packit b099d7
   
Packit b099d7
   if ((cb = XmOptionButtonGadget( (Widget) menu)) != NULL) {
Packit b099d7
       if (RC_OptionSubMenu(menu)) {
Packit b099d7
	   FindLargestOption
Packit b099d7
	       ((XmRowColumnWidget)RC_OptionSubMenu(menu), &width, &height );
Packit b099d7
Packit b099d7
	   if (LayoutIsRtoLG(cb))
Packit b099d7
	     width += Double(G_HighlightThickness(cb)) +
Packit b099d7
	       G_ShadowThickness(cb) + LabG_MarginLeft(cb) +
Packit b099d7
		 Double(MGR_ShadowThickness(RC_OptionSubMenu(menu))) - 2;
Packit b099d7
	   else  
Packit b099d7
	     width += Double(G_HighlightThickness(cb)) +
Packit b099d7
	       G_ShadowThickness(cb) + LabG_MarginRight(cb) +
Packit b099d7
		 Double(MGR_ShadowThickness(RC_OptionSubMenu(menu))) - 2;
Packit b099d7
	     
Packit b099d7
	   height += Double(G_HighlightThickness(cb)) + LabG_MarginTop(cb)
Packit b099d7
	       + LabG_MarginBottom(cb);
Packit b099d7
Packit b099d7
	   /* change cb if needed */
Packit b099d7
	   if ((width != XtWidth(cb)) || (height != XtHeight(cb))) {
Packit b099d7
Packit b099d7
	       /* we have pixels, but the cascade unit type might not be 
Packit b099d7
		  pixel, so save it and restore it after the setvalues */
Packit b099d7
	       unsigned char saved_unit_type = 
Packit b099d7
		   ((XmGadget)cb)->gadget.unit_type ;
Packit b099d7
Packit b099d7
	       ((XmGadget)cb)->gadget.unit_type = XmPIXELS;
Packit b099d7
	       XtVaSetValues (cb, XmNwidth, width, XmNheight, height, NULL);
Packit b099d7
	       ((XmGadget)cb)->gadget.unit_type = saved_unit_type;
Packit b099d7
	   }
Packit b099d7
       }
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
TopOrBottomAlignment(
Packit b099d7
	XmRowColumnWidget m,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
	int h,
Packit b099d7
	int shadow,
Packit b099d7
	int highlight,
Packit b099d7
	int baseline,		/* unused */
Packit b099d7
	int margin_top,
Packit b099d7
	int margin_height,
Packit b099d7
	int text_height,
Packit b099d7
#else
Packit b099d7
        Dimension h,
Packit b099d7
        Dimension shadow,
Packit b099d7
        Dimension highlight,
Packit b099d7
        Dimension baseline,	/* unused */
Packit b099d7
        Dimension margin_top,
Packit b099d7
        Dimension margin_height,
Packit b099d7
        Dimension text_height,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
	Dimension *new_height,
Packit b099d7
        int start_i,
Packit b099d7
        int end_i)
Packit b099d7
{
Packit b099d7
  XmRCKidGeometry kg = RC_Boxes (m);
Packit b099d7
Packit b099d7
  while (start_i < end_i)
Packit b099d7
  {
Packit b099d7
    if (XmIsGadget(kg [start_i].kid) || XmIsPrimitive(kg [start_i].kid))
Packit b099d7
    {
Packit b099d7
      XmBaselineMargins textMargins;
Packit b099d7
Packit b099d7
      _XmRC_SetOrGetTextMargins(kg[start_i].kid, XmBASELINE_GET, &textMargins);
Packit b099d7
      kg[start_i].margin_top = textMargins.margin_top;
Packit b099d7
      kg[start_i].margin_bottom = textMargins.margin_bottom;
Packit b099d7
    
Packit b099d7
      if (textMargins.shadow < shadow)
Packit b099d7
      {
Packit b099d7
         kg[start_i].margin_top += shadow - textMargins.shadow;
Packit b099d7
         kg[start_i].box.height += shadow - textMargins.shadow;
Packit b099d7
      }
Packit b099d7
      if (textMargins.highlight < highlight)
Packit b099d7
      {
Packit b099d7
         kg[start_i].margin_top += highlight - textMargins.highlight;
Packit b099d7
         kg[start_i].box.height += highlight - textMargins.highlight;
Packit b099d7
      }
Packit b099d7
      if (textMargins.margin_top < margin_top)
Packit b099d7
      {
Packit b099d7
         kg[start_i].margin_top += margin_top - textMargins.margin_top;
Packit b099d7
         kg[start_i].box.height += margin_top - textMargins.margin_top;
Packit b099d7
      }
Packit b099d7
      if (textMargins.margin_height < margin_height)
Packit b099d7
      {
Packit b099d7
         kg[start_i].margin_top += margin_height - textMargins.margin_height;
Packit b099d7
         kg[start_i].box.height += margin_height - textMargins.margin_height;
Packit b099d7
      }
Packit b099d7
      if (AlignmentBottom (m))
Packit b099d7
       if (textMargins.text_height < text_height)
Packit b099d7
       {
Packit b099d7
         kg[start_i].margin_top += text_height - textMargins.text_height;
Packit b099d7
         kg[start_i].box.height += text_height - textMargins.text_height;
Packit b099d7
       }
Packit b099d7
      if (kg[start_i].box.height < h)
Packit b099d7
      {
Packit b099d7
	kg[start_i].margin_bottom += h - kg[start_i].box.height;
Packit b099d7
        kg[start_i].box.height = h;
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
    if (kg[start_i].box.height > h)
Packit b099d7
      if (kg[start_i].box.height > *new_height)
Packit b099d7
        *new_height = kg[start_i].box.height;
Packit b099d7
    start_i++;
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
/*ARGSUSED*/
Packit b099d7
static void
Packit b099d7
BaselineAlignment(
Packit b099d7
	XmRowColumnWidget m,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
	int h,
Packit b099d7
	int shadow,		/* unused */
Packit b099d7
	int highlight,		/* unused */
Packit b099d7
	int baseline,
Packit b099d7
#else
Packit b099d7
        Dimension h,
Packit b099d7
        Dimension shadow,	/* unused */
Packit b099d7
        Dimension highlight,	/* unused */
Packit b099d7
        Dimension baseline,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
	Dimension *new_height,
Packit b099d7
        int start_i,
Packit b099d7
        int end_i)
Packit b099d7
{
Packit b099d7
   XmRCKidGeometry kg = RC_Boxes (m);
Packit b099d7
   XmBaselineMargins textMargins;
Packit b099d7
Packit b099d7
   while (start_i < end_i)
Packit b099d7
   {
Packit b099d7
     if (XmIsPrimitive (kg [start_i].kid) || XmIsGadget (kg [start_i].kid))
Packit b099d7
     {
Packit b099d7
      unsigned char label_type;
Packit b099d7
Packit b099d7
      _XmRC_SetOrGetTextMargins(kg [start_i].kid, XmBASELINE_GET, &textMargins);
Packit b099d7
      kg[start_i].margin_top = textMargins.margin_top;
Packit b099d7
      kg[start_i].margin_bottom = textMargins.margin_bottom;
Packit b099d7
      XtVaGetValues(kg [start_i].kid, XmNlabelType, &label_type, NULL);
Packit b099d7
Packit b099d7
      if (label_type == XmSTRING)
Packit b099d7
      {
Packit b099d7
        if (kg[start_i].baseline < baseline)
Packit b099d7
        {
Packit b099d7
          kg[start_i].margin_top += baseline - kg[start_i].baseline;
Packit b099d7
          if (kg[start_i].box.height + (baseline - kg[start_i].baseline) > h)
Packit b099d7
          {
Packit b099d7
            if (kg[start_i].box.height + (baseline - kg[start_i].baseline) > *new_height)
Packit b099d7
	      *new_height = kg[start_i].box.height + (baseline - kg[start_i].baseline);
Packit b099d7
	    kg[start_i].box.height += baseline - kg[start_i].baseline;
Packit b099d7
          }
Packit b099d7
          else
Packit b099d7
          {
Packit b099d7
	    kg[start_i].margin_bottom += h  - (kg[start_i].box.height +
Packit b099d7
					       (baseline - kg[start_i].baseline));
Packit b099d7
	    kg[start_i].box.height = h;
Packit b099d7
          }
Packit b099d7
        }
Packit b099d7
        else
Packit b099d7
        {
Packit b099d7
	  kg[start_i].margin_bottom += h  - (kg[start_i].box.height +
Packit b099d7
					     (baseline - kg[start_i].baseline));
Packit b099d7
	  kg[start_i].box.height = h;
Packit b099d7
        }
Packit b099d7
      }
Packit b099d7
      else
Packit b099d7
       kg[start_i].box.height = h;
Packit b099d7
    }
Packit b099d7
    else
Packit b099d7
      kg[start_i].box.height = h;
Packit b099d7
    start_i++;
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
static void
Packit b099d7
CenterAlignment(
Packit b099d7
        XmRowColumnWidget m,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int h,
Packit b099d7
#else
Packit b099d7
        Dimension h,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        int start_i,
Packit b099d7
        int end_i)
Packit b099d7
{
Packit b099d7
Packit b099d7
  XmRCKidGeometry kg = RC_Boxes (m);
Packit b099d7
Packit b099d7
  while(start_i < end_i)
Packit b099d7
  {
Packit b099d7
    if (XmIsGadget (kg [start_i].kid) || XmIsPrimitive (kg [start_i].kid))
Packit b099d7
    {
Packit b099d7
      XmBaselineMargins textMargins;
Packit b099d7
Packit b099d7
      _XmRC_SetOrGetTextMargins(kg [start_i].kid, XmBASELINE_GET, &textMargins);
Packit b099d7
      kg[start_i].margin_top = textMargins.margin_top;
Packit b099d7
      kg[start_i].margin_bottom = textMargins.margin_bottom;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    kg[start_i++].box.height = h;
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
static void 
Packit b099d7
ComputeTearOffHeight(
Packit b099d7
        XmRowColumnWidget m,
Packit b099d7
        Dimension *toc_b, 
Packit b099d7
        Dimension *b, 
Packit b099d7
	Dimension *toc_height,
Packit b099d7
        int *start_i, 
Packit b099d7
        int *child_i,
Packit b099d7
        int r)
Packit b099d7
Packit b099d7
{
Packit b099d7
    XmRCKidGeometry kg = RC_Boxes (m);
Packit b099d7
    
Packit b099d7
    *toc_b = *b = Double (RC_EntryBorder (m));
Packit b099d7
    
Packit b099d7
    if (RC_TearOffControl(m) && XtIsManaged(RC_TearOffControl(m))) {
Packit b099d7
	XmTearOffButtonWidget tw = (XmTearOffButtonWidget)RC_TearOffControl(m);
Packit b099d7
	
Packit b099d7
	if (!RC_EntryBorder(m) && kg[0].kid && XtIsWidget(kg[0].kid))
Packit b099d7
	    *toc_b = Double(kg[0].kid->core.border_width);
Packit b099d7
	
Packit b099d7
	*toc_height = 0;
Packit b099d7
	
Packit b099d7
	/* Remember!  If toc exists, it has the  first kid geo */
Packit b099d7
	for (*start_i = 1;  kg[*start_i].kid != NULL; (*start_i)++)
Packit b099d7
	    ASSIGN_MAX(*toc_height, kg[*start_i].box.height);
Packit b099d7
	
Packit b099d7
	*toc_height = *toc_height >> r;    /* r is 1 or 2 depending on the
Packit b099d7
					    orientation. 1 makes the tear off
Packit b099d7
					    half the highest, 2 makes 1/4 */
Packit b099d7
	
Packit b099d7
	ASSIGN_MAX(*toc_height, 2 + *toc_b +  2*
Packit b099d7
	       ((XmPrimitiveWidget)kg[0].kid)->primitive.shadow_thickness);
Packit b099d7
	
Packit b099d7
	/* Sync up the kid geo */
Packit b099d7
	/* Fix CR# 4778 */
Packit b099d7
	if (tw -> label.recompute_size == True)
Packit b099d7
	    kg[0].box.height = *toc_height;
Packit b099d7
	else
Packit b099d7
	    kg[0].box.height = *toc_height = XtHeight(tw);
Packit b099d7
	kg[0].box.width = XtWidth(m);
Packit b099d7
	
Packit b099d7
	*start_i = *child_i = 1;
Packit b099d7
    }
Packit b099d7
    else
Packit b099d7
	*toc_height = *toc_b = *start_i = *child_i = 0;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * figure out where all the children of a column style widget go.  The
Packit b099d7
 * border widths are already set.  
Packit b099d7
 *
Packit b099d7
 * In columnar mode, all heights and widths are identical.  They are the
Packit b099d7
 * size of the largest item.
Packit b099d7
 *
Packit b099d7
 * For vertical widgets the items are laid out in columns, going down the
Packit b099d7
 * first column and then down the second.  For horizonatal, think of the
Packit b099d7
 * columns as rows. 
Packit b099d7
 *
Packit b099d7
 * By convention incoming row column size can be zero, indicating a request
Packit b099d7
 * for preferred size, this means lay it out and record the needed size.
Packit b099d7
 *
Packit b099d7
 * NOTE: the layout is predicated on the help child being the last one since
Packit b099d7
 * it messes up the x, y for a following child.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
LayoutColumn(
Packit b099d7
        XmRowColumnWidget m,
Packit b099d7
        Dimension *m_width,     /* if 0 then caller's asking */
Packit b099d7
        Dimension *m_height )   /* if 0 then caller's asking */
Packit b099d7
{
Packit b099d7
    XmRCKidGeometry kg = RC_Boxes (m);
Packit b099d7
    XtWidgetGeometry *bx;
Packit b099d7
    Position x, y, max_x = 0, max_y = 0;
Packit b099d7
    int items_per_column,
Packit b099d7
        kid_i,
Packit b099d7
        child_i,                    /* which child we are doing */
Packit b099d7
        col_c   = 0,                /* items in col being done */
Packit b099d7
        start_i = 0;                /* index of first item in col */
Packit b099d7
    Dimension border, w, h, baseline, shadow, highlight, 
Packit b099d7
              margin_top, margin_height, text_height;
Packit b099d7
    Dimension toc_height;
Packit b099d7
    Dimension new_height= 0;
Packit b099d7
    Dimension toc_b, b;
Packit b099d7
Packit b099d7
Packit b099d7
    ComputeTearOffHeight(m, &toc_b, &b, &toc_height, &start_i, &child_i, 1);
Packit b099d7
Packit b099d7
    /* loc of first item */
Packit b099d7
    x = MGR_ShadowThickness(m) + RC_MarginW (m);
Packit b099d7
    y = MGR_ShadowThickness(m) + RC_MarginH (m) + toc_height + toc_b;
Packit b099d7
Packit b099d7
    GetMaxValues (m, &border, &w, &h, &items_per_column, &baseline, 
Packit b099d7
	      &shadow, &highlight, &margin_top, &margin_height, &text_height);
Packit b099d7
 
Packit b099d7
    if (!RC_EntryBorder(m) && kg[child_i].kid && XtIsWidget(kg[child_i].kid))
Packit b099d7
         b = Double(border);
Packit b099d7
Packit b099d7
    /* Loop through and find the new height, if any,  that the RowColumn */
Packit b099d7
    /* children need to grow to as a result of adjusting the baselines.  */
Packit b099d7
    /* The empty loop determine the number of kids                       */
Packit b099d7
Packit b099d7
    if (AlignmentBaselineTop(m) || AlignmentBaselineBottom(m))
Packit b099d7
    {
Packit b099d7
        kid_i = 0;
Packit b099d7
        while (kg [kid_i].kid != NULL)
Packit b099d7
	  kid_i++;
Packit b099d7
        BaselineAlignment(m, h, shadow, highlight, baseline, 
Packit b099d7
			  &new_height, 0, kid_i);
Packit b099d7
Packit b099d7
    }
Packit b099d7
    else if (AlignmentTop(m) || AlignmentBottom(m))
Packit b099d7
    {
Packit b099d7
        kid_i = 0; 
Packit b099d7
	while (kg [kid_i].kid != NULL)
Packit b099d7
	  kid_i++;
Packit b099d7
        TopOrBottomAlignment(m, h, shadow, highlight, 
Packit b099d7
			     baseline, margin_top, margin_height,
Packit b099d7
			     text_height, &new_height, 0, kid_i);     
Packit b099d7
    }
Packit b099d7
    else if (AlignmentCenter(m))
Packit b099d7
    {
Packit b099d7
        kid_i = 0; 
Packit b099d7
	while (kg [kid_i].kid != NULL)
Packit b099d7
	  kid_i++;
Packit b099d7
        CenterAlignment(m, h, start_i, kid_i);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (!new_height) new_height = h;
Packit b099d7
Packit b099d7
    for (; kg [child_i].kid != NULL; child_i++)
Packit b099d7
    {
Packit b099d7
        bx = &(kg[child_i].box);
Packit b099d7
Packit b099d7
        BWidth  (bx) = w;           /* all have same dimensions */
Packit b099d7
Packit b099d7
        if (AlignmentCenter(m))
Packit b099d7
         BHeight(bx) = h;
Packit b099d7
        
Packit b099d7
        if (++col_c > items_per_column)     /* start a new column */
Packit b099d7
        {
Packit b099d7
	   if (IsVertical (m))         /* calc loc of new column */
Packit b099d7
	   {
Packit b099d7
	      x += w + b + RC_Spacing (m);    /* to the right */
Packit b099d7
Packit b099d7
	      /*back at top of menu */
Packit b099d7
	      y = MGR_ShadowThickness(m) + RC_MarginH (m) + toc_height + toc_b;
Packit b099d7
	   }
Packit b099d7
	   else                /* calc loc of new row */
Packit b099d7
	   {
Packit b099d7
	      /* back to left edge */
Packit b099d7
	      x = MGR_ShadowThickness(m) + RC_MarginW (m);
Packit b099d7
	      /* down a row */
Packit b099d7
	      y += new_height + b + RC_Spacing (m);
Packit b099d7
	   }
Packit b099d7
Packit b099d7
	   col_c = 1;              /* already doing this one */
Packit b099d7
	   start_i = child_i;          /* record index */
Packit b099d7
        }
Packit b099d7
Packit b099d7
        if (IsHelp (m, ((Widget) kg[child_i].kid))) 
Packit b099d7
            CalcHelp (m, m_width, m_height, b, max_x, max_y, 
Packit b099d7
		       &x, &y, w, new_height);
Packit b099d7
Packit b099d7
        SetPosition (bx, x, y);         /* plunk him down */
Packit b099d7
Packit b099d7
        if (IsVertical (m))         /* get ready for next item */
Packit b099d7
            y += new_height + b + RC_Spacing (m);
Packit b099d7
        else
Packit b099d7
            x += w + b + RC_Spacing (m);
Packit b099d7
Packit b099d7
        ASSIGN_MAX (max_y, y); 
Packit b099d7
	ASSIGN_MAX (max_x, x); /* record for use later */
Packit b099d7
     }
Packit b099d7
Packit b099d7
     if (new_height > h) {
Packit b099d7
        for(kid_i = 0; kid_i < child_i; kid_i++) {
Packit b099d7
          bx = &(kg[kid_i].box);
Packit b099d7
          if (BHeight(bx) != new_height) {
Packit b099d7
	    kg[kid_i].margin_bottom += new_height - kg[kid_i].box.height;
Packit b099d7
	    BHeight(bx) = new_height;
Packit b099d7
          }
Packit b099d7
        }
Packit b099d7
     }
Packit b099d7
   
Packit b099d7
    SetAsking (m, m_width, m_height, b, max_x, max_y, x, y, w, new_height);
Packit b099d7
Packit b099d7
Packit b099d7
/* Set toc width to the width of the pane */
Packit b099d7
/* declare a macro and use it in the next 3 routines */
Packit b099d7
#define SET_TEAR_OFF_BOX(toc_height) \
Packit b099d7
   if (toc_height)    {\
Packit b099d7
       kg[0].box.x = MGR_ShadowThickness(m) + RC_MarginW (m);\
Packit b099d7
       kg[0].box.y = MGR_ShadowThickness(m) + RC_MarginH (m);\
Packit b099d7
       kg[0].box.height = toc_height;\
Packit b099d7
       kg[0].box.width = *m_width - Double(MGR_ShadowThickness(m) + \
Packit b099d7
       RC_MarginW(m)) - toc_b; \
Packit b099d7
    }
Packit b099d7
Packit b099d7
    SET_TEAR_OFF_BOX(toc_height);
Packit b099d7
Packit b099d7
    if (RC_AdjLast(m))
Packit b099d7
        AdjustLast (m, start_i, *m_width, *m_height);
Packit b099d7
    if (LayoutIsRtoLM(m))
Packit b099d7
        for (child_i=0; kg [child_i].kid != NULL; child_i++)
Packit b099d7
        {
Packit b099d7
           bx = &(kg[child_i].box);
Packit b099d7
           /* Adjust x */
Packit b099d7
           BX (bx) = *m_width - BX (bx) - BWidth (bx) - b ;
Packit b099d7
        }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * do a vertical tight (non-column) layout.
Packit b099d7
 *
Packit b099d7
 * In a tight layout one dimension of the items is left alone and the other
Packit b099d7
 * is kept uniform.  In a vertical row column widgets, the widths of each child 
Packit b099d7
 * are uniform for each column, the heights are never changed.  In a horiz 
Packit b099d7
 * row column widget, the widths are never changed and the heights are kept 
Packit b099d7
 * uniform for each row.
Packit b099d7
 *
Packit b099d7
 * It gets messy w.r.t. the help child because we don't know if there will
Packit b099d7
 * be room in the last column/row for it.  If there isn't room then a whole
Packit b099d7
 * new column/row has to be added.
Packit b099d7
 *
Packit b099d7
 * NOTE: the layout is predicated on the help child being the last one since
Packit b099d7
 * it messes up the x, y for a following child.
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
LayoutVerticalTight(
Packit b099d7
        XmRowColumnWidget m,
Packit b099d7
        Dimension *m_width,     /* if 0 then caller's asking */
Packit b099d7
        Dimension *m_height )   /* if 0 then caller's asking */
Packit b099d7
{
Packit b099d7
    XmRCKidGeometry kg = RC_Boxes (m);
Packit b099d7
    XtWidgetGeometry *bx;
Packit b099d7
    Position x, y, max_y = 0;
Packit b099d7
    Dimension h = 0;
Packit b099d7
    Dimension w = 0;                /* widest item width in col */
Packit b099d7
    int child_i, start_i;
Packit b099d7
    Dimension toc_height;
Packit b099d7
    Dimension toc_b, b;
Packit b099d7
    Dimension border = 0;
Packit b099d7
    
Packit b099d7
    ComputeTearOffHeight(m, &toc_b, &b, &toc_height, &start_i, &child_i, 1);
Packit b099d7
Packit b099d7
    /* first item location */
Packit b099d7
    x = MGR_ShadowThickness(m) + RC_MarginW (m);
Packit b099d7
    y = MGR_ShadowThickness(m) + RC_MarginH (m) + toc_height + toc_b;
Packit b099d7
Packit b099d7
    for (; kg [child_i].kid != NULL; child_i++)
Packit b099d7
    {
Packit b099d7
       bx = &(kg[child_i].box);
Packit b099d7
       if (!RC_EntryBorder(m) && kg[child_i].kid &&
Packit b099d7
	   XtIsWidget(kg[child_i].kid))
Packit b099d7
         b = Double(kg[child_i].kid->core.border_width);
Packit b099d7
Packit b099d7
       h = BHeight (bx) + b;           /* calc this item's height */
Packit b099d7
Packit b099d7
       if (((y + h) > *m_height) && 
Packit b099d7
	   ( ! Asking (*m_height)) &&
Packit b099d7
	   (child_i))
Packit b099d7
       {                   /* start new column */
Packit b099d7
	  while (start_i < child_i)
Packit b099d7
	      kg[start_i++].box.width = w;    /* set uniform width */
Packit b099d7
Packit b099d7
	  x += w + Double(border) 
Packit b099d7
	      + MGR_ShadowThickness(m)
Packit b099d7
		  + RC_MarginW (m);       /* go right and */
Packit b099d7
            
Packit b099d7
	  y = MGR_ShadowThickness(m)
Packit b099d7
	      + RC_MarginH (m) + toc_height + toc_b;  /* back to top of menu */
Packit b099d7
Packit b099d7
	  w = BWidth (bx);            /* reset for new column */
Packit b099d7
Packit b099d7
          if (kg[child_i].kid && XtIsWidget(kg[child_i].kid))
Packit b099d7
            border = kg[child_i].kid->core.border_width;
Packit b099d7
          else
Packit b099d7
            border = ((XmGadget)kg[child_i].kid)->rectangle.border_width;
Packit b099d7
       }
Packit b099d7
Packit b099d7
       if (IsHelp (m, ((Widget) kg[child_i].kid))) 
Packit b099d7
	   CalcHelp (m, m_width, m_height, b, 0, max_y, &x, &y, w, h);
Packit b099d7
Packit b099d7
       SetPosition (bx, x, y);
Packit b099d7
Packit b099d7
       ASSIGN_MAX(w, BWidth (bx));
Packit b099d7
Packit b099d7
       if (kg[child_i].kid && XtIsWidget(kg[child_i].kid))
Packit b099d7
       {
Packit b099d7
         if (border < kg[child_i].kid->core.border_width)
Packit b099d7
           border = kg[child_i].kid->core.border_width;
Packit b099d7
       }
Packit b099d7
       else
Packit b099d7
       {
Packit b099d7
         if (border < ((XmGadget)kg[child_i].kid)->rectangle.border_width)
Packit b099d7
           border = ((XmGadget)kg[child_i].kid)->rectangle.border_width;
Packit b099d7
       }
Packit b099d7
Packit b099d7
       y += h + RC_Spacing (m);        /* loc of next item */
Packit b099d7
Packit b099d7
       ASSIGN_MAX(max_y, y);       /* record for use later */
Packit b099d7
    }
Packit b099d7
Packit b099d7
    SetAsking (m, m_width, m_height, Double(border), 0, max_y, x, y, w, h);
Packit b099d7
Packit b099d7
    /* Set toc width to the width of the pane */
Packit b099d7
    SET_TEAR_OFF_BOX(toc_height);
Packit b099d7
Packit b099d7
    if (RC_AdjLast(m))
Packit b099d7
        AdjustLast (m, start_i, *m_width, *m_height);
Packit b099d7
    else
Packit b099d7
	while (start_i < child_i)
Packit b099d7
	    kg[start_i++].box.width = w;    /* set uniform width */
Packit b099d7
    if (LayoutIsRtoLM(m))
Packit b099d7
        for (child_i=0; kg [child_i].kid != NULL; child_i++)
Packit b099d7
        {
Packit b099d7
           bx = &(kg[child_i].box);
Packit b099d7
           /* Adjust x */
Packit b099d7
           BX (bx) = *m_width - BX (bx) - BWidth (bx) - b ;
Packit b099d7
        }
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
static void 
Packit b099d7
LayoutHorizontaltight(
Packit b099d7
        XmRowColumnWidget m,
Packit b099d7
        Dimension *m_width,     /* if 0 then caller's asking */
Packit b099d7
        Dimension *m_height )   /* if 0 then caller's asking */
Packit b099d7
{
Packit b099d7
    XmRCKidGeometry kg = RC_Boxes (m);
Packit b099d7
    XtWidgetGeometry *bx;
Packit b099d7
    Position x, y, max_x = 0;
Packit b099d7
    Dimension w = 0;
Packit b099d7
    Dimension h = 0;                   /* tallest item height in row */
Packit b099d7
    Dimension new_height = 0;
Packit b099d7
    Dimension baseline = 0;
Packit b099d7
    Dimension shadow = 0;
Packit b099d7
    Dimension highlight = 0;
Packit b099d7
    Dimension margin_height = 0;
Packit b099d7
    Dimension margin_top = 0;
Packit b099d7
    Dimension text_height = 0;
Packit b099d7
    Dimension border = 0;
Packit b099d7
    int child_i, start_i;                /* index of first item in row */
Packit b099d7
    Dimension toc_height;
Packit b099d7
    Dimension toc_b, b;
Packit b099d7
    
Packit b099d7
    ComputeTearOffHeight(m, &toc_b, &b, &toc_height, &start_i, &child_i, 2);
Packit b099d7
    
Packit b099d7
    /* first item location */
Packit b099d7
    x = MGR_ShadowThickness(m) + RC_MarginW (m);
Packit b099d7
    y = MGR_ShadowThickness(m) + RC_MarginH (m) + toc_height + toc_b;
Packit b099d7
    
Packit b099d7
    for (; kg [child_i].kid != NULL; child_i++) {
Packit b099d7
	bx = &(kg[child_i].box);
Packit b099d7
	if (!RC_EntryBorder(m) && kg[child_i].kid &&
Packit b099d7
	    XtIsWidget(kg[child_i].kid))
Packit b099d7
	    b = Double(kg[child_i].kid->core.border_width);
Packit b099d7
	    
Packit b099d7
	w = BWidth (bx) + b;            /* item's width */
Packit b099d7
	    
Packit b099d7
	if (((x + w) > *m_width) && 
Packit b099d7
	    ( ! Asking (*m_width)) &&
Packit b099d7
	    (child_i)) {                   /* start a new row */
Packit b099d7
		    
Packit b099d7
	    if (AlignmentBaselineTop(m) || AlignmentBaselineBottom(m))
Packit b099d7
		BaselineAlignment(m, h, shadow, highlight, baseline, 
Packit b099d7
				  &new_height, start_i, child_i);
Packit b099d7
	    else if (AlignmentTop(m) || AlignmentBottom(m))
Packit b099d7
		TopOrBottomAlignment(m, h, shadow, highlight, 
Packit b099d7
				     baseline, margin_top, margin_height,
Packit b099d7
				     text_height, &new_height, 
Packit b099d7
				     start_i, child_i);
Packit b099d7
	    else if (AlignmentCenter(m))
Packit b099d7
		CenterAlignment(m, h, start_i, child_i);
Packit b099d7
		    
Packit b099d7
	    if (new_height > h) {
Packit b099d7
		while (start_i < child_i) {
Packit b099d7
		    if (kg[start_i].box.height != new_height) {
Packit b099d7
		      kg[start_i].margin_bottom += 
Packit b099d7
			new_height - kg[start_i].box.height;
Packit b099d7
		      kg[start_i].box.height = new_height;
Packit b099d7
		    }
Packit b099d7
		    start_i++;
Packit b099d7
		}
Packit b099d7
		h = new_height;
Packit b099d7
	    }
Packit b099d7
		    
Packit b099d7
	    start_i = child_i;
Packit b099d7
		    
Packit b099d7
	    x = MGR_ShadowThickness(m) 
Packit b099d7
		+ RC_MarginW (m);       /* left edge of menu */
Packit b099d7
		    
Packit b099d7
	    y += h + Double(border) + MGR_ShadowThickness(m) 
Packit b099d7
		+ RC_MarginH (m);       /* down to top of next row */
Packit b099d7
		    
Packit b099d7
	    h = BHeight (bx);           /* reset for this row */
Packit b099d7
	    new_height = 0;
Packit b099d7
	    baseline = kg[child_i].baseline;
Packit b099d7
	    if (kg[child_i].kid && XtIsWidget (kg[child_i].kid))
Packit b099d7
		border = kg[child_i].kid->core.border_width;
Packit b099d7
	    else if (XmIsGadget (kg[child_i].kid))
Packit b099d7
		border = ((XmGadget)kg[child_i].kid)->rectangle.border_width;
Packit b099d7
		    
Packit b099d7
	    if (XmIsGadget (kg[child_i].kid) || 
Packit b099d7
		XmIsPrimitive (kg[child_i].kid)) {
Packit b099d7
		XmBaselineMargins textMargins;
Packit b099d7
		
Packit b099d7
		_XmRC_SetOrGetTextMargins(kg[child_i].kid, XmBASELINE_GET, 
Packit b099d7
					  &textMargins);
Packit b099d7
		shadow = textMargins.shadow;
Packit b099d7
		highlight = textMargins.highlight;
Packit b099d7
		margin_top = textMargins.margin_top;
Packit b099d7
		text_height = textMargins.text_height;
Packit b099d7
		margin_height = textMargins.margin_height;
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
	    
Packit b099d7
	if (IsHelp (m, ((Widget) kg[child_i].kid))) 
Packit b099d7
	    CalcHelp (m, m_width, m_height, b, max_x, 0, &x, &y, w, h);
Packit b099d7
	
Packit b099d7
	SetPosition (bx, x, y);
Packit b099d7
	    
Packit b099d7
	if (XmIsGadget (kg[child_i].kid) || XmIsPrimitive (kg[child_i].kid))
Packit b099d7
	  ASSIGN_MAX(baseline, kg[child_i].baseline);
Packit b099d7
Packit b099d7
	ASSIGN_MAX(h, BHeight (bx));
Packit b099d7
	
Packit b099d7
	if (kg[child_i].kid && XtIsWidget (kg[child_i].kid)) {
Packit b099d7
	    ASSIGN_MAX(border, kg[child_i].kid->core.border_width);
Packit b099d7
	} else if (XmIsGadget (kg[child_i].kid)) {
Packit b099d7
	    ASSIGN_MAX(border, 
Packit b099d7
		      ((XmGadget)kg[child_i].kid)->rectangle.border_width);
Packit b099d7
	}
Packit b099d7
	
Packit b099d7
	if (XmIsGadget (kg[child_i].kid) || XmIsPrimitive (kg[child_i].kid))
Packit b099d7
	    {
Packit b099d7
		XmBaselineMargins textMargins;
Packit b099d7
		
Packit b099d7
		_XmRC_SetOrGetTextMargins(kg[child_i].kid, XmBASELINE_GET, 
Packit b099d7
					  &textMargins);
Packit b099d7
		ASSIGN_MAX(shadow, textMargins.shadow);
Packit b099d7
		ASSIGN_MAX(highlight, textMargins.highlight);
Packit b099d7
		ASSIGN_MAX(margin_top, textMargins.margin_top);
Packit b099d7
		ASSIGN_MAX(text_height, textMargins.text_height);
Packit b099d7
		ASSIGN_MAX(margin_height, textMargins.margin_height);
Packit b099d7
	    }
Packit b099d7
	
Packit b099d7
	x += w + RC_Spacing (m);        /* loc of next item */
Packit b099d7
	
Packit b099d7
	ASSIGN_MAX (max_x, x);      /* record for use later */
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    /* Set toc width to the width of the pane */
Packit b099d7
    SET_TEAR_OFF_BOX(toc_height);
Packit b099d7
    
Packit b099d7
    
Packit b099d7
    if (AlignmentBaselineTop(m) || AlignmentBaselineBottom(m))
Packit b099d7
	BaselineAlignment(m, h, shadow, highlight, baseline, 
Packit b099d7
			  &new_height, start_i, child_i);
Packit b099d7
    else if (AlignmentTop(m) || AlignmentBottom(m))
Packit b099d7
	TopOrBottomAlignment(m, h, shadow, highlight, 
Packit b099d7
			     baseline, margin_top, margin_height,
Packit b099d7
			     text_height, &new_height, start_i, child_i);
Packit b099d7
    else if (AlignmentCenter(m))
Packit b099d7
	CenterAlignment(m, h, start_i, child_i);
Packit b099d7
    
Packit b099d7
    if (new_height > h){
Packit b099d7
	while (start_i < child_i){
Packit b099d7
		bx = &(kg[start_i].box);
Packit b099d7
		if (BHeight(bx) != new_height) {
Packit b099d7
		  kg[start_i].margin_bottom += 
Packit b099d7
		    new_height - kg [start_i].box.height;
Packit b099d7
		  BHeight(bx) = new_height;
Packit b099d7
		}
Packit b099d7
		start_i++;
Packit b099d7
	    }
Packit b099d7
    }
Packit b099d7
    
Packit b099d7
    if (new_height > h)
Packit b099d7
	SetAsking (m, m_width, m_height, Double(border), 
Packit b099d7
		    max_x, 0, x, y, w, new_height);
Packit b099d7
    else
Packit b099d7
	SetAsking (m, m_width, m_height, Double(border), 
Packit b099d7
		    max_x, 0, x, y, w, h);
Packit b099d7
    
Packit b099d7
#ifdef FIX_1521
Packit b099d7
    for (child_i = 0; kg[child_i].kid != NULL; child_i++)
Packit b099d7
    {
Packit b099d7
        bx = &(kg[child_i].box);
Packit b099d7
        ASSIGN_MIN(BWidth(bx), *m_width - Double(MGR_ShadowThickness(m))
Packit b099d7
            - Double(RC_MarginW(m)) - Double(BBorder(bx)));
Packit b099d7
        if (IsHelp(m, ((Widget) kg[child_i].kid)))
Packit b099d7
            ASSIGN_MAX(BX(&(kg[child_i].box)), MGR_ShadowThickness(m) + RC_MarginW(m));
Packit b099d7
    }
Packit b099d7
#endif
Packit b099d7
    if (RC_AdjLast(m))
Packit b099d7
	AdjustLast (m, start_i, *m_width, *m_height);
Packit b099d7
    else
Packit b099d7
	while (start_i < child_i) {
Packit b099d7
	    if (new_height > h) kg[start_i++].box.height = new_height;
Packit b099d7
	    else kg[start_i++].box.height = h;   /* set uniform height */
Packit b099d7
	}
Packit b099d7
    if (LayoutIsRtoLM(m))
Packit b099d7
        for (child_i=0; kg [child_i].kid != NULL; child_i++)
Packit b099d7
        {
Packit b099d7
           bx = &(kg[child_i].box);
Packit b099d7
           /* Adjust x */
Packit b099d7
           BX (bx) = *m_width - BX (bx) - BWidth (bx) - b ;
Packit b099d7
        }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * wrap a box around the entries, used with packing mode of none.
Packit b099d7
 *
Packit b099d7
 * we ignore negative positioning, ie. only worry about being wide enough
Packit b099d7
 * for the right edge of the rightmost entry (similarly for height)
Packit b099d7
 */
Packit b099d7
static void 
Packit b099d7
LayoutNone(
Packit b099d7
        XmRowColumnWidget m,
Packit b099d7
        Dimension *m_width,
Packit b099d7
        Dimension *m_height )
Packit b099d7
{
Packit b099d7
    XtWidgetGeometry *b;
Packit b099d7
    XmRCKidGeometry kg = RC_Boxes (m);
Packit b099d7
    int i, dum;
Packit b099d7
    Dimension w, max_w = 0, max_h = 0;
Packit b099d7
    Dimension toc_height;
Packit b099d7
    Dimension toc_b, bw;
Packit b099d7
    short temp;
Packit b099d7
    
Packit b099d7
    ComputeTearOffHeight(m, &toc_b, &bw, &toc_height, &dum, &i, 2);
Packit b099d7
Packit b099d7
    for (; kg [i].kid != NULL; i++)
Packit b099d7
      {
Packit b099d7
        b = &(kg[i].box);
Packit b099d7
        if (!RC_EntryBorder(m) && kg[i].kid && XtIsWidget(kg[i].kid))
Packit b099d7
             bw = Double(kg[i].kid->core.border_width);
Packit b099d7
Packit b099d7
        if (Asking (*m_width))
Packit b099d7
        {
Packit b099d7
	    /* be careful about negative positions */
Packit b099d7
            w = BWidth (b) + bw;
Packit b099d7
            temp = ((short)w) + BX (b);
Packit b099d7
            if (temp <= 0)
Packit b099d7
                w = 1;
Packit b099d7
            else
Packit b099d7
                w = (Dimension) temp;
Packit b099d7
Packit b099d7
            ASSIGN_MAX (max_w, w); 
Packit b099d7
        }
Packit b099d7
Packit b099d7
        if (Asking (*m_height))
Packit b099d7
        {
Packit b099d7
            /* be careful about negative positions */
Packit b099d7
            w = BHeight (b) + Double (bw);
Packit b099d7
            temp = ((short)w) + BY (b);
Packit b099d7
            if (temp <= 0)
Packit b099d7
                w = 1;
Packit b099d7
            else
Packit b099d7
                w = (Dimension) temp;
Packit b099d7
Packit b099d7
            ASSIGN_MAX (max_h, w); 
Packit b099d7
        }
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* Set toc width to the width of the pane */
Packit b099d7
    SET_TEAR_OFF_BOX(toc_height);
Packit b099d7
Packit b099d7
    if (Asking (*m_width)) *m_width  = max_w;
Packit b099d7
    if (Asking (*m_height)) *m_height = max_h;
Packit b099d7
}
Packit b099d7
Packit b099d7

Packit b099d7
/*
Packit b099d7
 * Routine used to determine the size of the option menu or to layout
Packit b099d7
 * the option menu given the current size.  The boolean calcMenuDimension
Packit b099d7
 * indicates whether the dimensions of the menu should be recalculated.
Packit b099d7
 * This is true when called from _XmRCThinkAboutSize and false when called
Packit b099d7
 * from AdaptToSize.
Packit b099d7
 *
Packit b099d7
 * This combines the two routines from Motif1.1: think_about_option_size
Packit b099d7
 * and option_layout.  Also new for Motif 1.2, the instigator is considered.
Packit b099d7
 * If the instigator is the label or the cascabebuttongadget, then the
Packit b099d7
 * dimensions are honored if they are large enough.
Packit b099d7
 */
Packit b099d7
/* ARGSUSED */
Packit b099d7
static void 
Packit b099d7
LayoutOptionAndSize (
Packit b099d7
        register XmRowColumnWidget menu,
Packit b099d7
        Dimension *width,
Packit b099d7
        Dimension *height,
Packit b099d7
        Widget instigator,
Packit b099d7
        XtWidgetGeometry *request,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int calcMenuDimension )
Packit b099d7
#else
Packit b099d7
        Boolean calcMenuDimension )
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
{
Packit b099d7
   XtWidgetGeometry    *label_box = NULL, *button_box = NULL;
Packit b099d7
   Dimension c_width; 
Packit b099d7
   Dimension c_height;
Packit b099d7
   register XmRowColumnWidget p = (XmRowColumnWidget) RC_OptionSubMenu(menu);
Packit b099d7
   XmCascadeButtonGadget cb = 
Packit b099d7
      (XmCascadeButtonGadget)XmOptionButtonGadget( (Widget) menu);
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * if this is being destroyed, don't get new dimensions.  This routine
Packit b099d7
    * assumes that cb is valid.
Packit b099d7
    */
Packit b099d7
Packit b099d7
   if (menu->core.being_destroyed)
Packit b099d7
   {
Packit b099d7
       if (calcMenuDimension)
Packit b099d7
       {
Packit b099d7
           *width = XtWidth(menu);
Packit b099d7
           *height = XtHeight(menu);
Packit b099d7
       }
Packit b099d7
       return;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   /* Find the interesting boxes */
Packit b099d7
Packit b099d7
   if (!XtIsManaged(XmOptionLabelGadget( (Widget) menu))) {
Packit b099d7
       button_box = &(RC_Boxes(menu)[0].box);
Packit b099d7
   } else {
Packit b099d7
       label_box = &(RC_Boxes(menu)[0].box);
Packit b099d7
       button_box = &(RC_Boxes(menu)[1].box);
Packit b099d7
   }
Packit b099d7
Packit b099d7
Packit b099d7
   if (p)
Packit b099d7
   {
Packit b099d7
      c_width = c_height = 0;
Packit b099d7
Packit b099d7
      FindLargestOption( p, &c_width, &c_height );
Packit b099d7
Packit b099d7
      if (LayoutIsRtoLG(cb)) 
Packit b099d7
	c_width += Double(G_HighlightThickness(cb)) + G_ShadowThickness(cb) +
Packit b099d7
	           LabG_MarginLeft(cb) + Double(MGR_ShadowThickness(p))  -
Packit b099d7
		   /* magic value */ 2;
Packit b099d7
      else
Packit b099d7
	c_width += Double(G_HighlightThickness(cb)) + G_ShadowThickness(cb) +
Packit b099d7
	           LabG_MarginRight(cb) + Double(MGR_ShadowThickness(p))  -
Packit b099d7
		   /* magic value */ 2;
Packit b099d7
      c_height += Double(G_HighlightThickness(cb)) + LabG_MarginTop(cb)
Packit b099d7
		 + LabG_MarginBottom(cb);
Packit b099d7
      
Packit b099d7
      /* allow settings in cbg to be honored if greater than best size */
Packit b099d7
      if (instigator == (Widget) cb)
Packit b099d7
      {
Packit b099d7
	  if ((request->request_mode & CWHeight) &&
Packit b099d7
	      (request->height > c_height))
Packit b099d7
	  {
Packit b099d7
	      c_height = request->height;
Packit b099d7
	  }
Packit b099d7
	  if ((request->request_mode & CWWidth) &&
Packit b099d7
	      (request->width > c_width))
Packit b099d7
	  {
Packit b099d7
	      c_width = request->width;
Packit b099d7
	  }
Packit b099d7
      }
Packit b099d7
      BWidth(button_box) = c_width;
Packit b099d7
      BHeight(button_box) = c_height;
Packit b099d7
  }
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
      /* Option menu draws a toggle indicator with a childless submenu */
Packit b099d7
      c_width = BWidth(button_box);
Packit b099d7
      c_height = BHeight(button_box);
Packit b099d7
   }
Packit b099d7
Packit b099d7
   /* treat separate the case where the label is unmanaged */
Packit b099d7
   if (!XtIsManaged(XmOptionLabelGadget( (Widget) menu))) {
Packit b099d7
Packit b099d7
       if (!calcMenuDimension &&  c_height > XtHeight(menu))
Packit b099d7
	   c_height = XtHeight(menu) - 2*RC_MarginH(menu);
Packit b099d7
Packit b099d7
       if (!calcMenuDimension && c_width > XtWidth (menu))
Packit b099d7
	   c_width = XtWidth(menu) - 2*RC_MarginW(menu);
Packit b099d7
      
Packit b099d7
       BWidth(button_box) = c_width;
Packit b099d7
       BHeight(button_box) = c_height;
Packit b099d7
Packit b099d7
       BX(button_box) = RC_MarginW(menu);
Packit b099d7
       BY(button_box) = RC_MarginH(menu);
Packit b099d7
Packit b099d7
       if (calcMenuDimension)
Packit b099d7
	   {
Packit b099d7
	       *width = c_width + 2*RC_MarginW(menu);
Packit b099d7
	       *height = c_height + 2*RC_MarginH(menu);
Packit b099d7
	   }
Packit b099d7
       return ;
Packit b099d7
   }
Packit b099d7
Packit b099d7
   if (IsHorizontal(menu))
Packit b099d7
   {
Packit b099d7
      /*
Packit b099d7
       * Set the height to the highest of the two but if calcMenuDimension
Packit b099d7
       * is false, limit it to the size of the option menu
Packit b099d7
       */
Packit b099d7
Packit b099d7
      if (BHeight(label_box) > c_height)
Packit b099d7
	  c_height = BHeight(label_box);
Packit b099d7
Packit b099d7
      if (!calcMenuDimension &&  c_height > XtHeight(menu))
Packit b099d7
	  c_height = XtHeight(menu) - 2*RC_MarginH(menu);
Packit b099d7
Packit b099d7
      BHeight(label_box) = c_height;
Packit b099d7
      BHeight(button_box) = c_height;
Packit b099d7
Packit b099d7
      /* The label box is placed at... */
Packit b099d7
      /* The button is placed just next to the label */
Packit b099d7
      /* Reverse if RtoL */
Packit b099d7
Packit b099d7
      if (LayoutIsRtoLM(menu)) {
Packit b099d7
	BX(button_box) = RC_MarginW(menu);
Packit b099d7
	BX(label_box) = BX(button_box) + BWidth(button_box) + RC_Spacing(menu);
Packit b099d7
      } else {
Packit b099d7
	BX(label_box) = RC_MarginW(menu);
Packit b099d7
	BX(button_box) = BX(label_box) + BWidth(label_box) + RC_Spacing(menu);
Packit b099d7
      }
Packit b099d7
      BY(label_box) = RC_MarginH(menu);
Packit b099d7
      BY(button_box) = RC_MarginH(menu);
Packit b099d7
Packit b099d7
      if (calcMenuDimension)
Packit b099d7
      {
Packit b099d7
	if (LayoutIsRtoLM(menu)) 
Packit b099d7
	  *width = BX(label_box) + BWidth(label_box) + RC_MarginW(menu);
Packit b099d7
	else 
Packit b099d7
	  *width = BX(button_box) + c_width + RC_MarginW(menu);
Packit b099d7
	*height = c_height + 2*RC_MarginH(menu);
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
   else	/* is vertical menu */
Packit b099d7
   {
Packit b099d7
      /*
Packit b099d7
       * Set the height to the highest of the two but if calcMenuDimension
Packit b099d7
       * is false, limit it to the size of the option menu
Packit b099d7
       */
Packit b099d7
      if (BWidth(label_box) > c_width)
Packit b099d7
	  c_width = BWidth(label_box);
Packit b099d7
Packit b099d7
      if (!calcMenuDimension && c_width > XtWidth (menu))
Packit b099d7
	  c_width = XtWidth(menu) - 2*RC_MarginW(menu);
Packit b099d7
      
Packit b099d7
      BWidth(label_box) = c_width;
Packit b099d7
      BWidth(button_box) = c_width;
Packit b099d7
Packit b099d7
      /* The label box is placed at... */
Packit b099d7
      BX(label_box) = RC_MarginW(menu);
Packit b099d7
      BY(label_box) = RC_MarginH(menu);
Packit b099d7
Packit b099d7
      /* The button is placed just below the label */
Packit b099d7
      BX(button_box) = RC_MarginW(menu);
Packit b099d7
      BY(button_box) = BY(label_box) + BHeight(label_box) + RC_Spacing(menu);
Packit b099d7
Packit b099d7
      if (calcMenuDimension)
Packit b099d7
      {
Packit b099d7
	  *width = c_width + 2*RC_MarginW(menu);
Packit b099d7
	  *height = BY(button_box) + c_height + RC_MarginH(menu);
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
void 
Packit b099d7
_XmRCThinkAboutSize(
Packit b099d7
        register XmRowColumnWidget m,
Packit b099d7
        Dimension *w,
Packit b099d7
        Dimension *h,
Packit b099d7
        Widget instigator,
Packit b099d7
        XtWidgetGeometry *request )
Packit b099d7
{
Packit b099d7
    if (!RC_ResizeWidth(m))  *w = XtWidth  (m);
Packit b099d7
    if (!RC_ResizeHeight(m)) *h = XtHeight (m);
Packit b099d7
Packit b099d7
    if (IsOption(m)) 
Packit b099d7
	LayoutOptionAndSize(m, w, h, instigator, request, TRUE);
Packit b099d7
    else if (PackNone (m))
Packit b099d7
        LayoutNone (m, w, h);
Packit b099d7
    else if (PackColumn (m)) 
Packit b099d7
	LayoutColumn (m, w, h);
Packit b099d7
    else {
Packit b099d7
	if (IsVertical (m)) 
Packit b099d7
	    LayoutVerticalTight (m, w, h);
Packit b099d7
	else 
Packit b099d7
	    LayoutHorizontaltight (m, w, h);
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (!RC_ResizeHeight(m) && !RC_ResizeWidth(m))
Packit b099d7
        return;
Packit b099d7
Packit b099d7
    ASSIGN_MAX(*w, RESOURCE_MIN_WIDTH);
Packit b099d7
    ASSIGN_MAX(*h, RESOURCE_MIN_HEIGHT);
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7
void 
Packit b099d7
_XmRCPreferredSize(
Packit b099d7
        XmRowColumnWidget m,
Packit b099d7
        Dimension *w,
Packit b099d7
        Dimension *h )
Packit b099d7
{
Packit b099d7
   Widget *q;
Packit b099d7
   int i;
Packit b099d7
   Dimension * baselines;
Packit b099d7
   int line_count;
Packit b099d7
   Dimension y;
Packit b099d7
Packit b099d7
   if ((!IsOption(m)) && ((PackColumn(m) && (IsVertical(m) || 
Packit b099d7
					     IsHorizontal(m))) ||
Packit b099d7
			  (PackTight(m) && IsHorizontal(m))))
Packit b099d7
   {
Packit b099d7
       if ((PackColumn(m) && (IsVertical(m) || IsHorizontal(m))) ||
Packit b099d7
         (PackTight(m) && IsHorizontal(m)))
Packit b099d7
     {
Packit b099d7
      if (*h == 0)
Packit b099d7
      {
Packit b099d7
       ForManagedChildren(m, i, q) /* reset Top and Bottom Margins that were */
Packit b099d7
       {                           /* set for vertical Alignment to work     */
Packit b099d7
          if (XmIsGadget(*q) || XmIsPrimitive(*q))
Packit b099d7
          {
Packit b099d7
            XmBaselineMargins textMargins;
Packit b099d7
Packit b099d7
            textMargins.margin_top = SavedMarginTop(*q);
Packit b099d7
            textMargins.margin_bottom = SavedMarginBottom(*q);
Packit b099d7
            _XmRC_SetOrGetTextMargins(*q, XmBASELINE_SET, &textMargins);
Packit b099d7
Packit b099d7
          }
Packit b099d7
       }
Packit b099d7
      }
Packit b099d7
     }
Packit b099d7
Packit b099d7
   /*
Packit b099d7
    * get array built for both widgets and gadgets layout is based only on 
Packit b099d7
    * this array, adjust width margins &  adjust height margins
Packit b099d7
    */
Packit b099d7
     RC_Boxes(m)=
Packit b099d7
       (XmRCKidGeometry)_XmRCGetKidGeo( (Widget) m, NULL, NULL, 
Packit b099d7
				    RC_EntryBorder(m),
Packit b099d7
				    RC_EntryBorder (m),
Packit b099d7
				    (IsVertical (m) && RC_DoMarginAdjust (m)),
Packit b099d7
				    (IsHorizontal (m) &&
Packit b099d7
				     RC_DoMarginAdjust (m)),
Packit b099d7
				    RC_HelpPb (m),
Packit b099d7
				    RC_TearOffControl(m),
Packit b099d7
				    XmGET_PREFERRED_SIZE);
Packit b099d7
     for (i = 0; RC_Boxes(m) [i].kid != NULL; i++)
Packit b099d7
     {
Packit b099d7
       Widget rc_kid;
Packit b099d7
       XmBaselineMargins textMargins;
Packit b099d7
       XRectangle displayRect;
Packit b099d7
       unsigned char label_type = XmSTRING;
Packit b099d7
       rc_kid = RC_Boxes(m) [i].kid;
Packit b099d7
Packit b099d7
       if (XmIsGadget (rc_kid) || XmIsPrimitive (rc_kid))
Packit b099d7
       {
Packit b099d7
	 XtVaGetValues(rc_kid, XmNlabelType, &label_type, NULL);
Packit b099d7
	 
Packit b099d7
	 if (label_type == XmSTRING)
Packit b099d7
	 {
Packit b099d7
	   if (XmIsLabel(rc_kid) || XmIsLabelGadget(rc_kid)) {
Packit b099d7
	     /* The baseline functions returns the baseline on the current size */
Packit b099d7
	     /* Since we need the preferred baseline, we need to calculate the y   */
Packit b099d7
	     /* coordinate on the preferred size and add this in to the baseline */
Packit b099d7
	     /* returned, after subtracting the y coordinate of the current widget */
Packit b099d7
	     _XmRC_SetOrGetTextMargins(rc_kid, XmBASELINE_GET, &textMargins);
Packit b099d7
	     y = (  textMargins.highlight + textMargins.shadow 
Packit b099d7
		  + textMargins.margin_height + textMargins.margin_top 
Packit b099d7
		  + ((  RC_Boxes(m) [i].box.height  
Packit b099d7
		      - textMargins.margin_top  
Packit b099d7
		      - textMargins.margin_bottom 
Packit b099d7
		      - (2 * (  textMargins.margin_height  
Packit b099d7
			      + textMargins.shadow
Packit b099d7
			      + textMargins.highlight)) 
Packit b099d7
		      - textMargins.text_height) / 2));
Packit b099d7
	     XmWidgetGetDisplayRect(rc_kid, &displayRect);
Packit b099d7
	   } 
Packit b099d7
	   else {
Packit b099d7
	     displayRect.y = y = 0;
Packit b099d7
	   }
Packit b099d7
Packit b099d7
	    if (AlignmentBaselineTop(m) || AlignmentBaselineBottom(m)) {
Packit b099d7
	      if (XmWidgetGetBaselines(rc_kid, &baselines, &line_count)) {
Packit b099d7
		if (AlignmentBaselineTop(m))
Packit b099d7
		    RC_Boxes(m) [i].baseline = baselines[0] - displayRect.y + y;
Packit b099d7
		else if (AlignmentBaselineBottom(m))
Packit b099d7
		    RC_Boxes(m) [i].baseline = baselines[line_count - 1] - 
Packit b099d7
		                               displayRect.y + y;
Packit b099d7
		XtFree((char *)baselines);
Packit b099d7
	      } 
Packit b099d7
	      else 
Packit b099d7
	      {
Packit b099d7
		RC_Boxes(m) [i].baseline = 0;
Packit b099d7
	      }
Packit b099d7
	    }
Packit b099d7
            RC_Boxes(m) [i].margin_top = 0;
Packit b099d7
            RC_Boxes(m) [i].margin_bottom = 0;
Packit b099d7
          }
Packit b099d7
          else
Packit b099d7
          {
Packit b099d7
            RC_Boxes(m) [i].baseline = 0;
Packit b099d7
            RC_Boxes(m) [i].margin_top = 0;
Packit b099d7
            RC_Boxes(m) [i].margin_bottom = 0;
Packit b099d7
          }
Packit b099d7
        }
Packit b099d7
      }
Packit b099d7
   }
Packit b099d7
   else
Packit b099d7
   {
Packit b099d7
     /*
Packit b099d7
      * get array built for both widgets and gadgets layout is based only on 
Packit b099d7
      * this array, adjust width margins &  adjust height margins
Packit b099d7
      */
Packit b099d7
      RC_Boxes(m)=
Packit b099d7
       (XmRCKidGeometry)_XmRCGetKidGeo( (Widget) m, NULL, NULL, 
Packit b099d7
				    RC_EntryBorder(m),
Packit b099d7
				    RC_EntryBorder (m),
Packit b099d7
				    (IsVertical (m) && RC_DoMarginAdjust (m)),
Packit b099d7
				    (IsHorizontal (m) &&
Packit b099d7
				     RC_DoMarginAdjust (m)),
Packit b099d7
				    RC_HelpPb (m),
Packit b099d7
				    RC_TearOffControl(m),
Packit b099d7
				    XmGET_PREFERRED_SIZE);
Packit b099d7
   }
Packit b099d7
Packit b099d7
   _XmRCThinkAboutSize (m, w, h, NULL, NULL);
Packit b099d7
Packit b099d7
   XtFree ((char *) RC_Boxes(m));
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Layout the row column widget to fit it's current size; ignore possible 
Packit b099d7
 * non-fitting of the entries into a too small row column widget.
Packit b099d7
 *
Packit b099d7
 * Don't forget the instigator.
Packit b099d7
 */
Packit b099d7
void 
Packit b099d7
_XmRCAdaptToSize(
Packit b099d7
        XmRowColumnWidget m,
Packit b099d7
        Widget instigator,
Packit b099d7
        XtWidgetGeometry *request )
Packit b099d7
{
Packit b099d7
   Dimension w = XtWidth (m);
Packit b099d7
   Dimension h = XtHeight (m);
Packit b099d7
   Dimension instigator_w = 0 ;
Packit b099d7
   Dimension instigator_h = 0;
Packit b099d7
   short i;
Packit b099d7
   Widget *q;
Packit b099d7
Packit b099d7
   if ((!IsOption(m)) && ((PackColumn(m) && (IsVertical(m) || IsHorizontal(m))) ||
Packit b099d7
       (PackTight(m) && IsHorizontal(m))))
Packit b099d7
   {
Packit b099d7
     ForManagedChildren(m, i, q)
Packit b099d7
     {
Packit b099d7
        if (XmIsGadget (*q) || XmIsPrimitive (*q))
Packit b099d7
        {
Packit b099d7
          XmBaselineMargins textMargins;
Packit b099d7
Packit b099d7
          textMargins.margin_top = SavedMarginTop(*q);
Packit b099d7
          textMargins.margin_bottom = SavedMarginBottom(*q);
Packit b099d7
          _XmRC_SetOrGetTextMargins(*q, XmBASELINE_SET, &textMargins);
Packit b099d7
        }
Packit b099d7
     }
Packit b099d7
   }
Packit b099d7
   /*
Packit b099d7
    * get array built for both widgets and gadgets,
Packit b099d7
    * layout is based only on this array,
Packit b099d7
    * adjust width margins and  adjust height margins
Packit b099d7
    */
Packit b099d7
   RC_Boxes(m) =
Packit b099d7
       (XmRCKidGeometry)_XmRCGetKidGeo( (Widget) m, instigator, request, 
Packit b099d7
				       RC_EntryBorder(m),
Packit b099d7
				       RC_EntryBorder (m),
Packit b099d7
				       (IsVertical (m) && 
Packit b099d7
					RC_DoMarginAdjust (m)),
Packit b099d7
				       (IsHorizontal (m) &&
Packit b099d7
					RC_DoMarginAdjust (m)),
Packit b099d7
				       RC_HelpPb (m),
Packit b099d7
				       RC_TearOffControl(m),
Packit b099d7
				       XmGET_PREFERRED_SIZE);
Packit b099d7
Packit b099d7
   if ((!IsOption(m)) && ((PackColumn(m) && (IsVertical(m) || 
Packit b099d7
					     IsHorizontal(m))) ||
Packit b099d7
			  (PackTight(m) && IsHorizontal(m))))
Packit b099d7
   {
Packit b099d7
     for (i = 0; RC_Boxes(m) [i].kid != NULL; i++)
Packit b099d7
     {
Packit b099d7
       if (XmIsGadget(RC_Boxes(m) [i].kid) || XmIsPrimitive(RC_Boxes(m) [i].kid))
Packit b099d7
       {
Packit b099d7
	 unsigned char label_type = XmSTRING;
Packit b099d7
	 RectObj ro = (RectObj) RC_Boxes(m) [i].kid;
Packit b099d7
	 
Packit b099d7
	 if (XtHeight (RC_Boxes(m) [i].kid) != RC_Boxes(m) [i].box.height)
Packit b099d7
         {
Packit b099d7
	   XmeConfigureObject( (Widget) ro, ro->rectangle.x, ro->rectangle.y,
Packit b099d7
			      ro->rectangle.width, RC_Boxes(m) [i].box.height, 
Packit b099d7
			      ro->rectangle.border_width);
Packit b099d7
	 }
Packit b099d7
	 
Packit b099d7
	 XtVaGetValues(RC_Boxes(m) [i].kid, XmNlabelType, &label_type, NULL);
Packit b099d7
Packit b099d7
	 if (label_type == XmSTRING &&
Packit b099d7
	     (AlignmentBaselineTop(m) || AlignmentBaselineBottom(m)))
Packit b099d7
	 {
Packit b099d7
	   Dimension *baselines;
Packit b099d7
	   int line_count;
Packit b099d7
	   
Packit b099d7
	   XmWidgetGetBaselines(RC_Boxes(m) [i].kid, &baselines, &line_count);
Packit b099d7
	   if (AlignmentBaselineTop(m))
Packit b099d7
	     RC_Boxes(m) [i].baseline = baselines[0];
Packit b099d7
	   else if (AlignmentBaselineBottom(m))
Packit b099d7
	     RC_Boxes(m) [i].baseline = baselines[line_count - 1];
Packit b099d7
	   XtFree((char *)baselines);
Packit b099d7
	 }
Packit b099d7
	 else
Packit b099d7
	   RC_Boxes(m) [i].baseline = 0;
Packit b099d7
Packit b099d7
       }
Packit b099d7
     }
Packit b099d7
   }
Packit b099d7
Packit b099d7
   if (IsOption(m))
Packit b099d7
       LayoutOptionAndSize (m, &w, &h, instigator, request, FALSE);
Packit b099d7
   else if (PackColumn (m)) 
Packit b099d7
       LayoutColumn (m, &w, &h);
Packit b099d7
   else if (!PackNone (m)) {
Packit b099d7
       if (IsVertical (m)) 
Packit b099d7
	   LayoutVerticalTight (m, &w, &h);
Packit b099d7
       else 
Packit b099d7
	   LayoutHorizontaltight (m, &w, &h);
Packit b099d7
   }
Packit b099d7
Packit b099d7
   if ((!IsOption(m)) && ((PackColumn(m) && (IsVertical(m) || IsHorizontal(m))) ||
Packit b099d7
       (PackTight(m) && IsHorizontal(m))))
Packit b099d7
   {
Packit b099d7
     for (i = 0; RC_Boxes(m) [i].kid != NULL; i++)
Packit b099d7
     {
Packit b099d7
       if (XmIsGadget(RC_Boxes(m) [i].kid) || XmIsPrimitive(RC_Boxes(m) [i].kid))
Packit b099d7
       {
Packit b099d7
         XmBaselineMargins textMargins;
Packit b099d7
Packit b099d7
         textMargins.margin_top = RC_Boxes(m) [i].margin_top;
Packit b099d7
         textMargins.margin_bottom = RC_Boxes(m) [i].margin_bottom;
Packit b099d7
         _XmRC_SetOrGetTextMargins(RC_Boxes(m) [i].kid, XmBASELINE_SET, &textMargins);
Packit b099d7
      
Packit b099d7
       }
Packit b099d7
     }
Packit b099d7
   }   
Packit b099d7
Packit b099d7
   if (instigator)
Packit b099d7
     {
Packit b099d7
       /* CR 5419: Save the original instigator dimensions */
Packit b099d7
       instigator_w = XtWidth(instigator);
Packit b099d7
       instigator_h = XtHeight(instigator);
Packit b099d7
     }
Packit b099d7
Packit b099d7
   _XmRCSetKidGeo ((XmRCKidGeometry)RC_Boxes(m), instigator);
Packit b099d7
Packit b099d7
   /*
Packit b099d7
   ** Hack alert!
Packit b099d7
   ** This is special code to enforce that the CBG in an option menu is
Packit b099d7
   ** kept correctly-sized when the items in this pulldown, associated with
Packit b099d7
   ** that cascade, change. There is no protocol for communicating this
Packit b099d7
   ** information nor any mechanism for adapting one; so we make the size
Packit b099d7
   ** request ourselves, here. The point is not that we are setting to the
Packit b099d7
   ** correct size so much as that the cascade's size is being adjusted after
Packit b099d7
   ** the menu size is fixed. calc_CBG_dims is probably being called an extra
Packit b099d7
   ** time to figure out the real size. This is not a frequent case.
Packit b099d7
    *
Packit b099d7
    * Do not call this routine below if this call was initiated by a geometry
Packit b099d7
    * request from an option menu's label or cascade button.  In that case,
Packit b099d7
    * the geometry has already been taken care of and must not be meddled
Packit b099d7
    * with or it will reset some values incorrectly.
Packit b099d7
    */
Packit b099d7
   if (!IsOption(m) || !instigator ||
Packit b099d7
       !((instigator == RC_Boxes(m)[0].kid) ||
Packit b099d7
	 (instigator == RC_Boxes(m)[1].kid)))
Packit b099d7
   {
Packit b099d7
       _XmRC_CheckAndSetOptionCascade(m);
Packit b099d7
   }
Packit b099d7
Packit b099d7
/* The old geometry management took care of resizing the instigator if
Packit b099d7
   XtGeometryYes was returned even if core.width and core.height had
Packit b099d7
   not changed. However this is not the case with the new geometry
Packit b099d7
   management. Therefore if margins have changed but not the core
Packit b099d7
   width and height label's resize needs to be called to calculate
Packit b099d7
   the x & y coordinates for the label text, with the new margins. */
Packit b099d7
Packit b099d7
   if ((instigator) && 
Packit b099d7
       (instigator_w == XtWidth(instigator)) &&
Packit b099d7
       (instigator_h == XtHeight(instigator)) &&
Packit b099d7
       (XmIsLabel(instigator) || XmIsLabelGadget(instigator)))
Packit b099d7
   {
Packit b099d7
     WidgetClass wc = XtClass(instigator);
Packit b099d7
     XtWidgetProc resize;
Packit b099d7
Packit b099d7
     _XmProcessLock();
Packit b099d7
     resize = wc->core_class.resize;
Packit b099d7
     _XmProcessUnlock();
Packit b099d7
     (*resize) ((Widget) instigator); 
Packit b099d7
   }
Packit b099d7
   /* Patch submitted by Kevin B. Hendrix of Java-Linux project. */
Packit b099d7
   if (RC_Boxes(m))
Packit b099d7
   {
Packit b099d7
     XtFree ( (char *) RC_Boxes(m));
Packit b099d7
     RC_Boxes(m) = NULL;
Packit b099d7
   }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
void
Packit b099d7
_XmRC_SetOrGetTextMargins(
Packit b099d7
        Widget wid,
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        unsigned int op,
Packit b099d7
#else
Packit b099d7
        unsigned char op,
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        XmBaselineMargins *textMargins )
Packit b099d7
{
Packit b099d7
  WidgetClass wc = XtClass(wid);
Packit b099d7
Packit b099d7
  if (op == XmBASELINE_GET) {
Packit b099d7
    /* in case the class does not have this procedure */
Packit b099d7
    bzero((void *) textMargins, sizeof(XmBaselineMargins));
Packit b099d7
  }
Packit b099d7
Packit b099d7
  textMargins->get_or_set = op;
Packit b099d7
Packit b099d7
  if (XmIsGadget(wid)) 
Packit b099d7
    {
Packit b099d7
      XmGadgetClassExt     *wcePtr;
Packit b099d7
      
Packit b099d7
      wcePtr = _XmGetGadgetClassExtPtr(wc, NULLQUARK);
Packit b099d7
      if (*wcePtr && (*wcePtr)->version == XmGadgetClassExtVersion &&
Packit b099d7
	  (*wcePtr)->widget_margins)
Packit b099d7
	(*((*wcePtr)->widget_margins)) (wid, textMargins) ;
Packit b099d7
    } 
Packit b099d7
  else if (XmIsPrimitive(wid)) 
Packit b099d7
    {
Packit b099d7
      XmPrimitiveClassExt  *wcePtr;
Packit b099d7
      
Packit b099d7
      wcePtr = _XmGetPrimitiveClassExtPtr(wc, NULLQUARK);
Packit b099d7
      if (*wcePtr && (*wcePtr)->widget_margins)
Packit b099d7
	(*((*wcePtr)->widget_margins)) (wid, textMargins) ;
Packit b099d7
  }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/**************************************************************** 
Packit b099d7
 * Assemble a kid box for each child widget and gadget, fill in data about
Packit b099d7
 *   each widget and optionally set up uniform border widths.
Packit b099d7
 * Returns a list of records, last one has a 'kid' field of NULL.  This memory
Packit b099d7
 *   for this list should eventually be freed with a call to XtFree().
Packit b099d7
 ****************/
Packit b099d7
/*ARGSUSED*/
Packit b099d7
XmRCKidGeometry
Packit b099d7
_XmRCGetKidGeo(
Packit b099d7
        Widget wid,                     /* Widget w/ children. */
Packit b099d7
        Widget instigator,              /* May point to a child who */
Packit b099d7
        XtWidgetGeometry *request,      /*   is asking to change. */
Packit b099d7
        int uniform_border,             /* T/F, enforce it. */
Packit b099d7
#if NeedWidePrototypes
Packit b099d7
        int border,
Packit b099d7
#else
Packit b099d7
        Dimension border,               /* Value to use if enforcing.*/
Packit b099d7
#endif /* NeedWidePrototypes */
Packit b099d7
        int uniform_width_margins,      /* unused, T/F, enforce it. */
Packit b099d7
        int uniform_height_margins,     /* unused, T/F, enforce it. */
Packit b099d7
        Widget help,                    /* May point to a help kid. */
Packit b099d7
	Widget toc,			/* May point to tear_off_control kid. */
Packit b099d7
        int geo_type )                  /* Actual or preferred. */
Packit b099d7
{
Packit b099d7
    CompositeWidget	c = (CompositeWidget) wid ;
Packit b099d7
    XmRCKidGeometry	geo ;
Packit b099d7
    Widget		kidWid ;
Packit b099d7
    int			i ;
Packit b099d7
    int			j = 0 ;
Packit b099d7
    Boolean		helpFound = FALSE ;
Packit b099d7
    Boolean		tocFound;
Packit b099d7
Packit b099d7
    tocFound = (toc && XtIsManaged(toc)) & 0x1;
Packit b099d7
Packit b099d7
    geo = (XmRCKidGeometry) XtMalloc((_XmGeoCount_kids(c) + 1 + tocFound) * 
Packit b099d7
       sizeof (XmRCKidGeometryRec));
Packit b099d7
Packit b099d7
    i = 0;
Packit b099d7
Packit b099d7
    if (tocFound)
Packit b099d7
    {
Packit b099d7
       geo[j].kid = toc ;
Packit b099d7
Packit b099d7
       _XmGeoLoadValues( toc, geo_type, instigator, request, &(geo[j].box));
Packit b099d7
Packit b099d7
       geo[j].margin_top = 0;
Packit b099d7
       geo[j].margin_bottom = 0;
Packit b099d7
       geo[j].baseline = 0;
Packit b099d7
Packit b099d7
Packit b099d7
       if (uniform_border)     /* if asked override border */
Packit b099d7
       {   
Packit b099d7
	  geo[j].box.border_width = border ;
Packit b099d7
       }
Packit b099d7
       j++ ;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* load all managed kids */
Packit b099d7
    for( ; i < c->composite.num_children ; i++    )
Packit b099d7
    {
Packit b099d7
       kidWid = c->composite.children[i] ;
Packit b099d7
       if (XtIsManaged( kidWid))
Packit b099d7
       {   
Packit b099d7
	  if(    kidWid == help    )
Packit b099d7
          {  /* Save to put help widget at the end of the widget list.*/
Packit b099d7
             helpFound = TRUE ;
Packit b099d7
          }
Packit b099d7
          else
Packit b099d7
	  {   
Packit b099d7
	     geo[j].kid = kidWid ;
Packit b099d7
Packit b099d7
	     _XmGeoLoadValues( kidWid, geo_type, instigator, request,
Packit b099d7
							       &(geo[j].box)) ;
Packit b099d7
             geo[j].margin_top = 0;
Packit b099d7
             geo[j].margin_bottom = 0;
Packit b099d7
             geo[j].baseline = 0;
Packit b099d7
Packit b099d7
	     /* Fix for CR 5598 - If the child is a separator widget 
Packit b099d7
		or gadget, set the width in the geo box to 0.  This 
Packit b099d7
		will take the separator out of the width consideration. */
Packit b099d7
	     /* Fix for 8131: only does that to Separators when packing
Packit b099d7
               if not none: this is the only time when it matters, plus
Packit b099d7
               pack_none does not correct the setting to 0 and the
Packit b099d7
               rowcolumn dies in protocol error later when trying to
Packit b099d7
               configure the separator to its 0 box.width or height */
Packit b099d7
 
Packit b099d7
	     if ((XmIsSeparator(kidWid) || XmIsSeparatorGadget(kidWid)) &&
Packit b099d7
		 (RC_Packing (c) != XmPACK_NONE)) {
Packit b099d7
		 unsigned char orientation;
Packit b099d7
		 Arg args[1];
Packit b099d7
Packit b099d7
		 XtSetArg(args[0], XmNorientation, &orientation);
Packit b099d7
		 XtGetValues(kidWid, args, 1);
Packit b099d7
Packit b099d7
		 if (orientation == XmHORIZONTAL)
Packit b099d7
		     geo[j].box.width = 0;
Packit b099d7
		 else
Packit b099d7
		     geo[j].box.height = 0;
Packit b099d7
             }
Packit b099d7
	     /* End fix for CR 5598 and 8131 */
Packit b099d7
Packit b099d7
	     
Packit b099d7
	     if (uniform_border)     /* if asked override border */
Packit b099d7
	     {   
Packit b099d7
		geo[j].box.border_width = border ;
Packit b099d7
	     }
Packit b099d7
	     j++ ;
Packit b099d7
	  }
Packit b099d7
       }
Packit b099d7
    }
Packit b099d7
Packit b099d7
    if (helpFound)                 /* put help guy into list */
Packit b099d7
    {
Packit b099d7
        geo[j].kid = help ;
Packit b099d7
Packit b099d7
        _XmGeoLoadValues( help, geo_type, instigator, request, &(geo[j].box)) ;
Packit b099d7
Packit b099d7
        geo[j].margin_top = 0;
Packit b099d7
        geo[j].margin_bottom = 0;
Packit b099d7
        geo[j].baseline = 0;
Packit b099d7
Packit b099d7
Packit b099d7
        if (uniform_border)         /* if asked override border */
Packit b099d7
        {   
Packit b099d7
	   geo[j].box.border_width = border ;
Packit b099d7
	}
Packit b099d7
        j++ ;
Packit b099d7
    }
Packit b099d7
    geo[j].kid = NULL ;                /* signal end of list */
Packit b099d7
Packit b099d7
    return( geo) ;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/**************************************************************** ARGSUSED
Packit b099d7
 * Take the kid geometry array and change each kid to match them.
Packit b099d7
 *   remember not to do the resize of the instigator.
Packit b099d7
 * The kid geometry "kg" is assumed to be fully specified.
Packit b099d7
 ****************/
Packit b099d7
void
Packit b099d7
_XmRCSetKidGeo(
Packit b099d7
        XmRCKidGeometry kg,
Packit b099d7
        Widget instigator )
Packit b099d7
{
Packit b099d7
    Widget          w ;
Packit b099d7
    XtWidgetGeometry * b ;
Packit b099d7
    int             i ;
Packit b099d7
/****************/
Packit b099d7
Packit b099d7
    for(i=0 ; kg[i].kid != NULL ; i++) {
Packit b099d7
        w = (Widget) kg[i].kid ;
Packit b099d7
        b = &(kg[i].box) ;
Packit b099d7
Packit b099d7
	if(    w != instigator    ) { 
Packit b099d7
	    XmeConfigureObject(w, b->x, b->y, b->width, b->height, 
Packit b099d7
			       b->border_width) ;
Packit b099d7
	} else {   
Packit b099d7
	    XtX( w) = b->x ;
Packit b099d7
	    XtY( w) = b->y ;
Packit b099d7
	    XtWidth( w) = b->width ;
Packit b099d7
	    XtHeight( w) = b->height ;
Packit b099d7
	    XtBorderWidth( w) = b->border_width ;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
    return ;
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
Packit b099d7

Packit b099d7
static void 
Packit b099d7
GetMenuKidMargins(
Packit b099d7
        XmRowColumnWidget m,
Packit b099d7
        Dimension *width,
Packit b099d7
        Dimension *height,
Packit b099d7
        Dimension *left,
Packit b099d7
        Dimension *right,
Packit b099d7
        Dimension *top,
Packit b099d7
        Dimension *bottom )
Packit b099d7
{
Packit b099d7
   register int i;
Packit b099d7
   Widget *q;
Packit b099d7
Packit b099d7
   *width = *height = *left = *right = *top = *bottom = 0;
Packit b099d7
Packit b099d7
   ForManagedChildren(m, i, q) {
Packit b099d7
	if (XmIsLabelGadget(*q)) {
Packit b099d7
	    ASSIGN_MAX(*width, LabG_MarginWidth  (*q));
Packit b099d7
	    ASSIGN_MAX(*height, LabG_MarginHeight (*q));
Packit b099d7
	    ASSIGN_MAX(*left, LabG_MarginLeft   (*q));
Packit b099d7
	    ASSIGN_MAX(*right, LabG_MarginRight  (*q));
Packit b099d7
	} else if (XmIsLabel(*q)) {
Packit b099d7
	    ASSIGN_MAX(*width, Lab_MarginWidth  (*q));
Packit b099d7
	    ASSIGN_MAX(*height, Lab_MarginHeight (*q));
Packit b099d7
	    ASSIGN_MAX(*left, Lab_MarginLeft   (*q));
Packit b099d7
	    ASSIGN_MAX(*right, Lab_MarginRight  (*q));
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    ForManagedChildren (m, i, q)
Packit b099d7
    {
Packit b099d7
      if (XmIsLabel(*q) || XmIsLabelGadget(*q))
Packit b099d7
      {
Packit b099d7
       if (SavedMarginTop(*q) > *top)
Packit b099d7
           *top = SavedMarginTop(*q);
Packit b099d7
       if (SavedMarginBottom(*q) > *bottom)
Packit b099d7
           *bottom = SavedMarginBottom(*q);
Packit b099d7
      }
Packit b099d7
    }
Packit b099d7
}
Packit b099d7
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Toggle buttons have this thingy hanging off the left of the
Packit b099d7
 * widget, before the text.  This dimension is known as the MarginLeft.
Packit b099d7
 * Pulldown's have hot spots in the MarginRight, accelerators go in the
Packit b099d7
 * marginRight also.
Packit b099d7
 *
Packit b099d7
 * For generality's sake we should insure that all
Packit b099d7
 * of the current label subclass widgets in the menu have the 
Packit b099d7
 * margins set to the same value.  
Packit b099d7
 */
Packit b099d7
void 
Packit b099d7
_XmRCDoMarginAdjustment(
Packit b099d7
        XmRowColumnWidget m )
Packit b099d7
{
Packit b099d7
    register Widget *p;
Packit b099d7
    register int i; 
Packit b099d7
    Dimension m_w, m_h, m_l, m_r, m_t, m_b;
Packit b099d7
    Dimension w, h;
Packit b099d7
Packit b099d7
    if ((!RC_DoMarginAdjust (m)) || (IsOption(m)))
Packit b099d7
    {
Packit b099d7
      ForManagedChildren (m, i, p)
Packit b099d7
      {
Packit b099d7
        if (XmIsGadget(*p) || XmIsPrimitive(*p))
Packit b099d7
        {
Packit b099d7
Packit b099d7
          XmBaselineMargins textMargins;
Packit b099d7
Packit b099d7
          _XmRC_SetOrGetTextMargins(*p, XmBASELINE_GET, &textMargins);
Packit b099d7
          SavedMarginTop(*p) = textMargins.margin_top;
Packit b099d7
          SavedMarginBottom(*p) = textMargins.margin_bottom;
Packit b099d7
          
Packit b099d7
        }
Packit b099d7
       }
Packit b099d7
       return;
Packit b099d7
    }
Packit b099d7
    /*
Packit b099d7
     * this should almost be part
Packit b099d7
     * of the layout process, except this requires a setvalue not a resize...
Packit b099d7
     */
Packit b099d7
Packit b099d7
    GetMenuKidMargins (m, &m_w, &m_h, &m_l, &m_r, &m_t, &m_b);
Packit b099d7
Packit b099d7
    ForManagedChildren (m, i, p)
Packit b099d7
    {
Packit b099d7
        if (XmIsLabelGadget(*p))
Packit b099d7
        {
Packit b099d7
            XmLabelGadget q;
Packit b099d7
	    XmLabelGCacheObjPart localCache;
Packit b099d7
            /*
Packit b099d7
             * If in a popup or pulldown pane,
Packit b099d7
             * don't do labels; i.e. only do buttons.
Packit b099d7
             */
Packit b099d7
            if (((*p)->core.widget_class == xmLabelGadgetClass) &&
Packit b099d7
                (IsPulldown(m) || IsPopup(m)))
Packit b099d7
                continue;
Packit b099d7
Packit b099d7
            w = XtWidth  (*p);
Packit b099d7
            h = XtHeight (*p);
Packit b099d7
Packit b099d7
            q = (XmLabelGadget) (*p);
Packit b099d7
Packit b099d7
            if (IsVertical (m)) 
Packit b099d7
            {
Packit b099d7
	       _XmQualifyLabelLocalCache(&localCache, q);
Packit b099d7
Packit b099d7
	       /* change horiz margins to  be uniform */
Packit b099d7
	       if (LabG_MarginLeft(q) != m_l)
Packit b099d7
	       {
Packit b099d7
		  w += m_l - LabG_MarginLeft(q);
Packit b099d7
		  _XmAssignLabG_MarginLeft_r((&localCache), m_l);
Packit b099d7
	       }
Packit b099d7
Packit b099d7
	       if (LabG_MarginRight(q) != m_r)
Packit b099d7
	       {
Packit b099d7
		  w += m_r - LabG_MarginRight(q);
Packit b099d7
		  _XmAssignLabG_MarginRight_r((&localCache), m_r);
Packit b099d7
	       }
Packit b099d7
Packit b099d7
	       if (LabG_MarginWidth(q) != m_w)
Packit b099d7
	       {
Packit b099d7
		  w += m_w - LabG_MarginWidth(q);
Packit b099d7
		  _XmAssignLabG_MarginWidth_r((&localCache), m_w);
Packit b099d7
	       }
Packit b099d7
       	       _XmReCacheLabG_r(&localCache, q);
Packit b099d7
Packit b099d7
	       if (q->rectangle.width != w) 
Packit b099d7
	       {
Packit b099d7
		  XmeConfigureObject( (Widget) q, q->rectangle.x,
Packit b099d7
                                        q->rectangle.y, w, q->rectangle.height,
Packit b099d7
                                                    q->rectangle.border_width);
Packit b099d7
	       }
Packit b099d7
            }
Packit b099d7
Packit b099d7
            if (!IsVertical (m) || PackColumn(m))
Packit b099d7
            {
Packit b099d7
	       _XmQualifyLabelLocalCache(&localCache, q);
Packit b099d7
Packit b099d7
	       /* change vert margins */
Packit b099d7
	       if (LabG_MarginTop(q) != m_t)
Packit b099d7
	       {
Packit b099d7
		  h += m_t - LabG_MarginTop(q);
Packit b099d7
		  _XmAssignLabG_MarginTop_r((&localCache), m_t);
Packit b099d7
	       }
Packit b099d7
Packit b099d7
	       if (LabG_MarginBottom(q) != m_b)
Packit b099d7
	       {
Packit b099d7
		  h += m_b - LabG_MarginBottom(q);
Packit b099d7
		  _XmAssignLabG_MarginBottom_r((&localCache), m_b);
Packit b099d7
	       }
Packit b099d7
	       
Packit b099d7
	       if (LabG_MarginHeight(q) != m_h)
Packit b099d7
	       {
Packit b099d7
		  h += m_h - LabG_MarginHeight(q);
Packit b099d7
		  _XmAssignLabG_MarginHeight_r((&localCache), m_h);
Packit b099d7
	       }
Packit b099d7
	       
Packit b099d7
	       _XmReCacheLabG_r(&localCache, q);
Packit b099d7
Packit b099d7
	       if (q->rectangle.height != h) 
Packit b099d7
	       {
Packit b099d7
		  XmeConfigureObject( (Widget) q, q->rectangle.x,
Packit b099d7
                                         q->rectangle.y, q->rectangle.width, h,
Packit b099d7
                                                    q->rectangle.border_width);
Packit b099d7
	       }
Packit b099d7
               SavedMarginTop(*p) = LabG_MarginTop (q);
Packit b099d7
               SavedMarginBottom(*p) = LabG_MarginBottom (q);
Packit b099d7
            }
Packit b099d7
	 }
Packit b099d7
        else if (XmIsLabel(*p))
Packit b099d7
        {
Packit b099d7
            XmLabelWidget lw;
Packit b099d7
            /*
Packit b099d7
             * If in a popup or pulldown pane,
Packit b099d7
             * don't do labels; i.e. only do buttons.
Packit b099d7
             */
Packit b099d7
            if (((*p)->core.widget_class == xmLabelWidgetClass) &&
Packit b099d7
                (IsPulldown(m) || IsPopup(m)))
Packit b099d7
                continue;
Packit b099d7
Packit b099d7
            w = XtWidth  (*p);
Packit b099d7
            h = XtHeight (*p);
Packit b099d7
Packit b099d7
            lw = (XmLabelWidget) (*p);
Packit b099d7
Packit b099d7
            if (IsVertical (m)) /* change horiz margins to */
Packit b099d7
            {                   /* be uniform */
Packit b099d7
               ChangeMargin (Lab_MarginLeft  (lw), m_l, w);
Packit b099d7
               ChangeMargin (Lab_MarginRight (lw), m_r, w);
Packit b099d7
               ChangeMargin (Lab_MarginWidth (lw), m_w, w);
Packit b099d7
Packit b099d7
               if (XtWidth (lw) != w) 
Packit b099d7
               {
Packit b099d7
                    XmeConfigureObject( (Widget) lw, lw->core.x, lw->core.y,
Packit b099d7
                                    w, lw->core.height, lw->core.border_width);
Packit b099d7
               }
Packit b099d7
            }
Packit b099d7
Packit b099d7
            if (!IsVertical (m) || PackColumn(m))      /* change vert margins */
Packit b099d7
            {
Packit b099d7
                ChangeMargin (Lab_MarginTop (lw), m_t, h);
Packit b099d7
                ChangeMargin (Lab_MarginBottom (lw), m_b, h);
Packit b099d7
                ChangeMarginDouble (Lab_MarginHeight (lw), m_h, h);
Packit b099d7
Packit b099d7
                if (XtHeight (lw) != h) 
Packit b099d7
                {
Packit b099d7
                    XmeConfigureObject( (Widget) lw, lw->core.x,lw->core.y,
Packit b099d7
                                     lw->core.width, h, lw->core.border_width);
Packit b099d7
                }
Packit b099d7
                SavedMarginTop(*p) = Lab_MarginTop (lw);
Packit b099d7
                SavedMarginBottom(*p) = Lab_MarginBottom (lw);
Packit b099d7
            }
Packit b099d7
        }
Packit b099d7
    }
Packit b099d7
}