#ifndef lint
#endif /* lint */
/***********************************************************
Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Digital or MIT not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
******************************************************************/
/*
* Paned.c - Paned Composite Widget.
*
* Updated and significantly modifided from the Athena VPaned Widget.
*
* Date: March 1, 1989
*
* By: Chris D. Peterson
* MIT X Consortium
* kit@expo.lcs.mit.edu
*/
#include <ctype.h>
#include <X11/IntrinsicP.h>
#include <X11/cursorfont.h>
#include <X11/StringDefs.h>
#include <./Xaw3_1XawInit.h>
#include <./Xaw3_1Grip.h>
#include <./Xaw3_1PanedP.h>
(childP)++ )
(childP)++ )
/*****************************************************************************
*
* Full instance record declaration
*
****************************************************************************/
static char defGripTranslations[] =
"<Btn1Down>: GripAction(Start, UpLeftPane) \n\
<Btn2Down>: GripAction(Start, ThisBorderOnly) \n\
<Btn3Down>: GripAction(Start, LowRightPane) \n\
<Btn1Motion>: GripAction(Move, UpLeft) \n\
<Btn2Motion>: GripAction(Move, ThisBorder) \n\
<Btn3Motion>: GripAction(Move, LowRight) \n\
Any<BtnUp>: GripAction(Commit)";
(caddr_t) "XtDefaultForeground"},
sizeof(XtTranslations),
/* Cursors - both horiz and vertical have to work. */
};
};
static void ClassInitialize(), Initialize();
static void Redisplay();
static void GetGCs(), ReleaseGCs();
static void RefigureLocationsAndCommit();
static XtGeometryResult GeometryManager();
static void ChangeManaged();
static void InsertChild();
static void DeleteChild();
static Boolean PaneSetValues();
static void PushPaneStack();
static void GetPaneStack();
static Boolean PopPaneStack();
static void ClearPaneStack();
{
/* core class fields */
/* class name */ "Paned",
/* size */ sizeof(PanedRec),
/* class_initialize */ ClassInitialize,
/* class_part init */ NULL,
/* class_inited */ FALSE,
/* initialize */ Initialize,
/* initialize_hook */ NULL,
/* realize */ Realize,
/* actions */ NULL,
/* num_actions */ 0,
/* resourses */ resources,
/* xrm_class */ NULLQUARK,
/* compress_motion */ TRUE,
/* compress_exposure */ TRUE,
/* compress_enterleave*/ TRUE,
/* visible_interest */ FALSE,
/* destroy */ ReleaseGCs,
/* resize */ Resize,
/* expose */ Redisplay,
/* set_values */ SetValues,
/* set_values_hook */ NULL,
/* set_values_almost */ XtInheritSetValuesAlmost,
/* get_values_hook */ NULL,
/* accept_focus */ NULL,
/* version */ XtVersion,
/* callback_private */ NULL,
/* tm_table */ NULL,
/* query_geometry */ XtInheritQueryGeometry,
/* display_accelerator*/ XtInheritDisplayAccelerator,
/* extension */ NULL
}, {
/* composite class fields */
/* geometry_manager */ GeometryManager,
/* change_managed */ ChangeManaged,
/* insert_child */ InsertChild,
/* delete_child */ DeleteChild,
/* extension */ NULL
}, {
/* constraint class fields */
/* subresourses */ subresources,
/* constraint_size */ sizeof(PanedConstraintsRec),
/* initialize */ NULL,
/* destroy */ NULL,
/* set_values */ PaneSetValues,
/* extension */ NULL
}
};
/* For compatability. */
/***********************************************************
*
* Private Functions.
*
************************************************************/
/* Function Name: AdjustPanedSize
* Description: Adjusts the size of the pane.
* Arguments: pw - the paned widget to adjust.
* off_size - the new off_size to use.
* result_ret - result of query ** RETURNED **
* on_size_ret - the new on_size ** RETURNED **
* off_size_ret - the new off_size ** RETURNED **
* Returns: the amount of change in size.
*/
static void
{
}
}
else {
}
if (result_ret != NULL) {
*on_size_ret = old_size;
*off_size_ret = off_size;
return;
}
if (*result_ret != XtGeometryAlmost) {
return;
}
return;
}
}
/* Function Name: PaneSize
* Description: returns the width or height of the pane depending
* upon the orientation we are using.
* Arguments: w - and widget.
* vertical - TRUE if this is vertically oriented pane.
* Returns: the size requested
*
* vertical - return height
* !vertical - return width
*/
static Dimension
Widget w;
{
}
/* Function Name: GetRequestInfo
* Description: returns request information.
* Arguments: geo_struct - a geometry struct to get information out of.
* vert - TRUE if this is a vertical paned widget.
* Returns: the request information.
*/
static Dimension
{
}
/* Function Name: ChoosePaneToResize.
* Description: This function chooses a pane to resize.
* They are choosen using the following rules:
*
* 1) size < max && size > min
* 2) skip adjust == FALSE
* 3) widget not its prefered height &&
* this change will bring it closer &&
* The user has not resized this pane.
*
* If no widgets are found that fits all the rules then
* rule #3 is broken.
* If there are still no widgets found than
* rule #2 is broken.
* Rule #1 is never broken.
* If no widgets are found then NULL is returned.
*
* Arguments: pw - the paned widget.
* index - the index of the current pane.
* dir - direction to search first.
* shrink - TRUE if we need to shrink a pane, FALSE otherwise.
* Returns: pane to resize or NULL.
*/
static Pane
int index;
{
backwords. */
}
while(TRUE) {
return(pane);
/*
* This is counter-intiutive, but if we are resizing the pane
* above the grip we want to choose a pane below the grip to lose,
* and visa-versa.
*/
/*
* If we have come to and edge then reduce the rule set, and try again.
* If we are reduced the rules to none, then return NULL.
*/
return(NULL);
}
}
}
/* Function Name: StatisfiesRule1
* Description: check for to see if this pane satisfies rule 1.
* Arguments: pane - the pane to check.
* shrink -TRUE if we want to shrink this pane, FALSE otherwise
* Returns: TRUE if the rule is satisfied.
*/
static Boolean
{
}
/* Function Name: StatisfiesRule2
* Description: check for to see if this pane satisfies rule 2.
* Arguments: pane - the pane to check.
* Returns: TRUE if the rule is satisfied.
*/
static Boolean
{
}
/* Function Name: StatisfiesRule3
* Description: check for to see if this pane satisfies rule 3.
* Arguments: pane - the pane to check.
* shrink -TRUE if we want to shrink this pane, FALSE otherwise
* Returns: TRUE if the rule is satisfied.
*/
static Boolean
{
return ( pane->paned_adjusted_me &&
}
/* Function Name: LoopAndRefigureChildren.
* Description: if we are resizeing either the UpleftPane or LowRight Pane
* loop through all the children to see if any will allow us
* to resize them.
* Arguments: pw - the paned widget.
* index - the number of the pane border we are moving.
* dir - the pane to move (either UpLeftPane or LowRightPane).
* sizeused - current amount of space used.
* THIS VALUE IS USED AND RETURNED.
* Returns: none.
*/
static void
{
/*
* Choose a pane to resize.
* First look on the Pane Stack, and then go hunting for another one.
* If we fail to find a pane to resize then give up.
*/
int start_size;
return; /* no one to resize, give up. */
from_stack = FALSE;
}
/*
* Try to resize this pane so that all panes will fit, take min and max
* into account.
*/
if (from_stack) {
if (shrink) {
} /* don't remove these braces. */
else
}
else if (rule3_ok) {
if (shrink) {
} /* don't remove these braces. */
else
}
}
}
/* Function Name: RefigureLocations
* Description: refigures all locations of children.
* Arguments: pw - the paned widget.
* index - child to start refiguring at.
* dir - direction to move from child.
* Returns: none.
*
* There are special arguements to index and dir, they are:
* index - NO_INDEX.
* dir - AnyPane.
*
* If either of these is true then all panes may be resized and
* the choosing of panes proceedes in reverse order starting with the
* last child.
*/
static void
int index;
{
int sizeused = 0;
/*
* Get an initial estimate of the size we will use.
*/
}
/*
* If we still are not the right size, then tell the pane that
* wanted to resize that it can't.
*/
}
/*
* It is possible that the panes will not fit inside the vpaned widget, but
* we have tried out best.
*
* Assign each pane a location.
*/
}
}
/* Function Name: CommitNewLocations
* Description: Commits all of the previously figured locations.
* Arguments: pw - the paned widget.
* Returns: none.
*/
static void
{
(Dimension) 0);
}
}
else {
(Dimension) 0);
}
}
/*
* This should match XtMoveWidget, except that we're also insuring the
* grip is Raised in the same request.
*/
}
}
}
/* Function Name: RefigureLocationsAndCommit
* Description: Refigures all locations in a paned widget and
* commits them immediatly.
* Arguments: pw - the paned widget.
* Returns: none
*
* This function does nothing if any of the following are true.
* o refiguremode is false.
* o The widget is unrealized.
* o There are no panes is the paned widget.
*
* NOTE: This is the resize Proceedure for the Paned widget.
*/
static void
Widget w;
{
}
}
/* Function Name: _DrawRect
* Description: Draws a rectangle in the proper orientation.
* Arguments: pw - the paned widget.
* gc - gc to used for the draw.
* on_olc, off_loc - location of upper left corner of rect.
* on_size, off_size - size of rectangle.
* Returns: none
*/
static void
{
else
}
/* Function Name: _DrawInternalBorders
* Description: Draws the internal borders into the paned widget.
* Arguments: pw - the paned widget.
* gc - the GC to use to draw the borders.
* Returns: none.
*/
static void
{
/*
* This is an optomization. Do not paint the internal borders if
* they are the same color as the background.
*/
return;
off_loc = 0;
}
}
/*
* This allows good reuse of code, as well as descriptive function names.
*/
/* Function Name: _DrawTrackLines
* Description: Draws the lines that animate the pane borders when the
* grips are moved.
* Arguments: pw - the Paned widget.
* erase - if True then just erase track lines, else
* draw them in.
* Returns: none.
*/
static void
{
off_loc = 0;
if (!erase) {
}
}
}
}
/*
* This allows good reuse of code, as well as descriptive function names.
*/
/* Function Name: GetEventLocation
* Description: Converts and event to an x and y locaion.
* Arguments: pw - the paned widget.
* event - a pointer to an event.
* Returns: if this is a vertical pane then (y) else (x).
*/
static int
{
int x, y;
case ButtonPress:
case ButtonRelease:
break;
case KeyPress:
case KeyRelease:
break;
case MotionNotify:
break;
default:
}
return(y);
return(x);
}
/* Function Name: StartGripAdjustment
* Description: Starts the grip adjustment proceedure.
* Arguments: pw - the paned widget.
* grip - the grip widget selected.
* dir - the direction that we are to be moving.
* Returns: none.
*/
static void
{
/*
* Change the cursor.
*/
if (XtIsRealized(grip)) {
if (dir == UpLeftPane)
else if (dir == LowRightPane)
else {
else
}
}
else {
if (dir == UpLeftPane)
else if (dir == LowRightPane)
else {
else
}
}
}
}
/* Function Name: MoveGripAdjustment
* Description: This routine moves all panes around when a grip is moved.
* Arguments: pw - the paned widget.
* grip - the grip that we are moving.
* dir - the direction the pane we are interested is w.r.t the
* grip.
* loc - location of pointer in proper direction.
* Returns: none.
*/
static void
int loc;
{
/*
* If moving this border only then do not allow either of the borders
* to go beyond the min or max size allowed.
*/
if ( (dir == ThisBorderOnly) ) {
if (add_size != old_add_size)
}
if (add_size != 0)
if (sub_size != 0)
}
/* Function Name: CommitGripAdjustment
* Description: Commits the grip adjustment.
* Arguments: pw - the paned widget.
* Returns: none
*/
{
/*
* Since the user selected this size then use it as the preferred size.
*/
}
}
}
/* Function Name: HandleGrip
* Description: Handles the grip manipulations.
* Arguments: grip - the grip widget that has been moved.
* junk - ** NOT USED **
* call_data - data passed to us from the grip widget.
* Returns: none.
*/
/* ARGSUSED */
static void
{
int loc;
char action_type;
if (call_data->num_params == 0 ||
XtError( "Paned GripAction has been passed incorrect parameters." );
if (action_type != 'C') {
else
}
switch (action_type) {
case 'S': /* Start adjustment */
break;
case 'M':
break;
case 'C':
break;
default:
XtError( "Paned GripAction(); 1st parameter invalid" );
}
}
/* Function Name: ResortChildren
* Description: Resorts the children so that all managed children
* are first.
* Arguments: pw - the paned widget.
* Returns: none.
*/
static void
{
unmanagedP = NULL;
/*
* We only keep track of the first unmanaged pane.
*/
if (unmanagedP == NULL)
unmanagedP = childP;
}
else { /* must be a managed pane */
/*
* If an earlier widget was not a managed pane, then swap
*/
if (unmanagedP != NULL) {
*unmanagedP = *childP;
}
}
}
}
/* Function Name: ManageAndUnmanageGrips
* Description: This function manages and unmanages the grips so that
* the managed state of each grip matches that of its pane.
* Arguments: pw - the paned widget.
* Returns: none.
*/
static void
{
if ( XtIsManaged(*childP) )
else
if (managedP != managed_grips) {
}
if (unmanagedP != unmanaged_grips)
}
/* Function Name: CreateGrip
* Description: Creates a grip widget.
* Arguments: child - the child that wants a grip to be created for it.
* Returns: none.
*/
static void
{
num_args++;
else
num_args++;
}
/* Function Name: GetGCs
* Description: Gets new GC's.
* Arguments: w - the paned widget.
* Returns: none.
*/
static void
GetGCs(w)
Widget w;
{
/*
* Draw pane borders in internal border color.
*/
/*
* Erase pane borders with background color.
*/
/*
* Draw Track lines (animate pane borders) in internal border color ^ bg color.
*/
}
/* Function Name: SetChildrenPrefSizes.
* Description: Sets the preferred sizes of the children.
* Arguments: pw - the paned widget.
* Returns: none.
*/
static void
{
else {
if( vert ) {
}
else {
}
== XtGeometryAlmost) &&
else
}
}
}
/* Function Name: ChangeAllGripCursors
* Description: Changes all the grip cursors.
* Arguments: pw - the paned widget.
* Returns: none
*/
static void
{
else
}
}
}
/************************************************************
*
* Stack Manipulation routines (Private).
*
************************************************************/
/* Function Name: PushPaneStack
* Description: Pushes a value onto the pane stack.
* Arguments: pw - the paned widget.
* pane - the pane that we are pushing.
* Returns: none.
*/
static void
{
}
/* Function Name: GetPaneStack
* Description: Gets the top value from the pane stack.
* Arguments: pw - the paned widget.
* shrink - TRUE if we want to shrink this pane,
* FALSE otherwise.
* ** RETURNED ** pane - the pane that we are popping.
* ** RETURNED ** start_size - the size that this pane started at.
* Returns: none.
*/
static void
int * start_size;
{
return;
}
}
/* Function Name: PopPaneStack
* Description: Pops the top item off the pane stack.
* Arguments: pw - the paned widget.
* Returns: TRUE if this is not the last element on the stack.
*/
static Boolean
{
return(TRUE);
}
/* Function Name: ClearPaneStack
* Description: removes all entries from the pane stack.
* Arguments: pw - the paned widget.
* Returns: none
*/
static void
{
while(PopPaneStack(pw));
}
/************************************************************
*
* Semi-public routines.
*
************************************************************/
/* Function Name: ClassInitialize
* Description: The Paned widgets class initialization proc.
* Arguments: none.
* Returns: none.
*/
static void
{
}
/* The Geometry Manager only allows changes after Realize if
* allow_resize is True in the constraints record.
*
* For vertically paned widgets:
*
* It only allows height changes, but offers the requested height
* as a compromise if both width and height changes were requested.
*
* For horizontal widgets the coverse is true.
* As all good Geometry Managers should, we will return No if the
* request will have no effect; i.e. when the requestor is already
* of the desired geometry.
*/
Widget w;
{
/*
* If any of the following is true, disallow the geometry change.
*
* o The paned widget is realized and allow_resize is false for the pane.
* o The child did not ask to change the on_size.
* o The request is not a width or height request.
* o The requested size is the same as the current size.
*/
return XtGeometryNo;
}
&off_size);
/*
* Fool the Refigure Locations proc to thinking that we are
* a different on_size;
*/
if (result != XtGeometryNo)
if (vert)
else
/*
* Set up reply struct and reset core on_size.
*/
if (vert) {
}
else {
}
/*
* IF either of the following is true.
*
* o There was a "off_size" request and the new "off_size" is different
* from that requested.
* o There was no "off_size" request and the new "off_size" is different
*
* o The "on_size" we will allow is different from that requested.
*
* THEN: set almost
*/
if (vert)
else
if (almost) return XtGeometryAlmost;
}
else {
}
return XtGeometryDone;
}
/* ARGSUSED */
{
}
static void
Widget w;
{
/*
* Before we commit the new locations we need to realize all the panes and
* their grips.
*/
XtRealizeWidget( *childP );
}
} /* Realize */
static void
ReleaseGCs(w)
Widget w;
{
}
static void InsertChild(w)
register Widget w;
{
/* insert the child widget in the composite children list with the */
/* superclass insert_child routine. */
if (!IsPane(w)) return;
/* ||| Panes will be added in the order they are created, temporarilly */
CreateGrip(w);
}
else {
}
} /* InsertChild */
static void DeleteChild(w)
Widget w;
{
/* remove the subwidget info and destroy the grip */
/* delete the child widget in the composite children list with the */
/* superclass delete_child routine. */
} /* DeleteChild */
static void ChangeManaged(w)
Widget w;
{
/*
* If the size is zero then set it to the size of the widest or tallest pane.
*/
size = 1;
}
if ( XtIsManaged(*childP) ) {
}
else
break; /* This list is already sorted. */
/*
* ForAllPanes can now be used.
*/
} /* ChangeManaged */
/* Function Name: Resize
* Description: The paned widget's resize proc.
* Arguments: w - the paned widget.
* Returns: none.
*/
static void
Resize(w)
Widget w;
{
}
/* ARGSUSED */
static void
Widget w;
{
DrawInternalBorders( (PanedWidget) w);
}
/* ARGSUSED */
static Boolean
{
}
}
/*
* We are fooling the paned widget into thinking that is needs to
* fully refigure everything, which is what we want.
*/
else
return(TRUE);
}
return(TRUE); /* We have done a full configuration, return.*/
}
(XtIsRealized(new)) ) {
}
return (redisplay);
} /* SetValues */
/* ARGSUSED */
static Boolean
{
/* Check for new min and max. */
/* Check for change in XtNshowGrip. */
happen automatically at realize time.*/
}
}
}
/* ||| need to look at position changes */
return(redisplay);
}
/************************************************************
*
* Public routines.
*
************************************************************/
/* Function Name: XawPanedSetMinMax
* Description: Sets the min and max size for a pane.
* Arguments: widget - the widget that is a child of the Paned widget.
* min, max - the new min and max size for the pane.
* Returns: none.
*/
void
{
}
/* Function Name: XawPanedGetMinMax
* Description: Gets the min and max size for a pane.
* Arguments: widget - the widget that is a child of the Paned widget.
** RETURNED ** min, max - the current min and max size for the pane.
* Returns: none.
*/
void
{
}
/* Function Name: XawPanedSetRefigureMode
* Description: Allows a flag to be set the will inhibit
* the paned widgets relayout routine.
* Arguments: w - the paned widget.
* mode - if FALSE then inhibit refigure.
* Returns: none.
*/
void
Widget w;
{
}
/* Function Name: XawPanedGetNumSub
* Description: Returns the number of panes in the paned widget.
* Arguments: w - the paned widget.
* Returns: the number of panes in the paned widget.
*/
int
Widget w;
{
}
/* Function Name: XawPanedAllowResize
* Description: Allows a flag to be set that determines if the paned
* widget will allow geometry requests from this child
* Arguments: widget - a child of the paned widget.
* Returns: none.
*/
void
{
}