mikew@wyse.wyse.com (Mike Wexler) (09/14/88)
Submitted-by: rlh2@ukc.ac.uk Posting-number: Volume 1, Issue 37 Archive-name: menupane/part01 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 1)." # Contents: Makefile MenuPane.3x MenuPane.c MenuPane.h MenuPaneP.h # README TMstate.cdif menutest.c panetest.c patchlevel.h # Wrapped by mikew@x2 on Tue Sep 13 13:46:24 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f Makefile -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"Makefile\" else echo shar: Extracting \"Makefile\" \(138 characters\) sed "s/^X//" >Makefile <<'END_OF_Makefile' XOBJS = menutest.o XCFLAGS=-I/usr/new/usr/include XXLIBS = -L/usr/new/usr/lib -lXaw -lXt -lX11 X Xmenutest: $(OBJS) X cc -o $@ $(OBJS) $(XLIBS) END_OF_Makefile if test 138 -ne `wc -c <Makefile`; then echo shar: \"Makefile\" unpacked with wrong size! fi # end of overwriting check fi if test -f MenuPane.3x -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"MenuPane.3x\" else echo shar: Extracting \"MenuPane.3x\" \(4390 characters\) sed "s/^X//" >MenuPane.3x <<'END_OF_MenuPane.3x' X.\" X.\" Add simple keeps to MAN macros so .TS/.TE will work X.\" X.de KS \" Keep start X.br X.in 0 X.di KP X.. X.de KE \" Keep end X.br X.di X.ne \\n(dnu X.nr fI \\n(.u X.nf X.KP X.if \\n(fI .fi X.in X.. X.TH "MenuPane" 3X X.na X.nh X.SH NAME XMenuPaneWidgetClass \- An X Widget for creating menu panes. X.SH SYNOPSIS X\fB X.B #include <X11/StringDefs.h> X.br X.B #include <X11/Intrinsic.h> X.br X.br X.B #include "MenuPane.h" X\fR X.SH CLASSES XA subclass of Core, Composite and ConstraintClass. X.P XThe widget class to use when creating a X.I MenuPane\^ Xwidget is \fBmenuPaneWidgetClass\fP. X.P XThe class name of X.I MenuPane\^ Xis "MenuPane". X.SH DESCRIPTION XThe \fIMenuPane\fP provides a convenient method for creating menus. The X\fIMenuPane\fP looks after its children in either a horizontal or vertical Xarrangement and resizes its managed children proportionally to the change Xin its size. A \fIMenuPane\fP will only control children who are in its Xcurrently managed set. When a child is managed or unmanaged and the X\fIMenuPane\fP has been realized, its siblings are resized to make room for Xthe new child or to take up the child's space. The \fIMenuPane\fP never Xmakes requests to its parent for a change in its geometry and is content Xwith whatever geometry it is given. \fIMenuPane\fP widgets can be nested Xto allow for a combination of vertical and horizontal menu layouts in Xa parent menu. Children of a \fIMenuPane\fP are normally of the \fICommand\fP Xsubclass, however any class of widget is accepted by a \fIMenuPane\fP. XChildren of a vertical \fIMenuPane\fP are laid out from top to bottom with Xtheir borders overlapping. Children of a horizontal \fIMenuPane\fP are laid out Xfrom side to side with their borders overlapping. Children are laid out in Xthe order that they were created (by calls to XtCreateWidget). Therefore Xif a child becomes managed it is placed immeadiately below/to the side of Xthe sibling that was created before it. The size of a \fIMenuPane\fP Xdefaults to the size of its parent. X.SH "NEW RESOURCES" XTo specify any of these resources within a resource defaults file, Xsimply drop the \fIXtN\fP prefix from the resource name. X.I MenuPane\^ Xdefines the following new resources: X.sp 1 X.KS X.TS Xcenter allbox; XcB sss XlB lB lB lB Xllll. XMenuPane Resource Set XName Class Type Default X_ XXtNvertPane XtCVertpane Boolean TRUE XXtNaskChild XtCAskchild Boolean TRUE X.TE X.KE X.sp 1 X.IP \fBXtNvertPane\fP XIndicates whether the pane is considered vertical (TRUE) or horizontal X(FALSE). Vertical panes position their children so that their widths Xare the same as the pane's width. A child's height is not initially decided by Xthe pane. Children are laid out top to bottom. XHorizontal panes position their children so that their heights are the same Xas the pane's height. A child's width is not initially decided by the pane. XChildren are laid out side by side. XThe pane does however control resizing of its children. X.IP \fBXtNaskChild\fP XIf TRUE the pane will ask its children their preferred size (using XXtQueryGeometry) whenever a child becomes managed or unmanaged. XIf FALSE the pane will assume the childs current size is preferred. X.SH "CONSTRAINT RESOURCES" XNo public constraint resources are added by the \fIMenuPane\fP class. X.bp X.SH "INHERITED RESOURCES" XThe following resources are inherited from the named superclasses: X.sp 1 X.KS X.TS Xcenter allbox; XcB sss XlB lB lB lB Xllll. XCore Resource Set -- CORE(3X) XName Class Type Default X_ XXtNscreen XtCScreen XScreen * 0 XXtNcolormap XtCColormap Pointer NULL XXtNancestorSensitive XtCAncestorSenstitive Boolean TRUE XXtNx XtCX int 0 XXtNy XtCY int 0 XXtNwidth XtCWidth int 10 XXtNheight XtCHeight int 10 XXtNdepth XtCDepth int 0 XXtNbackground XtCBackground Pixel White XXtNborderWidth XtCBorderWidth int 0 XXtNborder XtCBorder Pixel Black XXtNsensitive XtCSensitive Boolean TRUE XXtNmappedWhenManaged XtCMappedWhenManaged Boolean TRUE XXtNdestroyCallback XtCCallback Pointer NULL X.TE X.KE X.sp 1 X.SH "TRANSLATIONS" XThere are no default translations in the \fIMenuPane\fP class. X.SH "ACTIONS" XThere are no actions added by the \fIMenuPane\fP class. X.SH AUTHOR XRichard Hesketh. X.br XComputing Lab., University of Kent at Canterbury, UK. X.SH SEE ALSO X\fIpanetest\fP - example test program using \fIMenuPane\fP's X.br X\fIProgramming With the X Widgets\fP, X.br X\fIX Toolkit Intrinsics - C Language X Interface\fP, X.br X\fIXlib - C Language Interface, Protocol Version 11\fP. END_OF_MenuPane.3x if test 4390 -ne `wc -c <MenuPane.3x`; then echo shar: \"MenuPane.3x\" unpacked with wrong size! fi # end of overwriting check fi if test -f MenuPane.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"MenuPane.c\" else echo shar: Extracting \"MenuPane.c\" \(11055 characters\) sed "s/^X//" >MenuPane.c <<'END_OF_MenuPane.c' X#ifndef lint Xstatic char rcsid[] = "$Header: MenuPane.c,v 1.2 88/08/23 18:11:05 rlh2 Exp $"; X#endif lint X X/********************************************************************** X * MenuPaneWidget * X * (c) 1988 Richard Hesketh / rlh2@ukc.ac.uk * X * Computing Lab. University of Kent at Canterbury * X * * X * Subclass of constraintWidgetClass :looks after its children either * X * horizontally or vertically arranged * X ********************************************************************** X X This software is in the Public Domain and as such can be freely copied X and distributed provided this notice and the author's name is included. X*/ X X#include <stdio.h> X#include <ctype.h> X#include <X11/Xos.h> X#include <X11/IntrinsicP.h> X#include <X11/StringDefs.h> X#include "MenuPaneP.h" X X#define CONSTRAINTS_MANAGED(w) (((MPConstraint)w->core.constraints)->menuPane.managed_done) X Xstatic void Initialize(); Xstatic void Resize(); Xstatic void Realize(); Xstatic XtGeometryResult Geometry_handler(); Xstatic void Change_managed(); Xstatic XtGeometryResult MenuPane_geometry(); Xstatic void constraint_Initialize(); X X/* X * New resources added by this subclass :- X * X * XtNvertPane - if TRUE pane is vertically arranged, FALSE = horizontal. X * XtNaskChild - if TRUE the child is asked what size it prefers. X */ Xstatic XtResource resources[] = { X { XtNvertPane, XtCVertpane, XtRBoolean, sizeof(Boolean), X XtOffset(MenuPaneWidget, menuPane.vert_pane), XtRString, "TRUE"}, X { XtNaskChild, XtCAskchild, XtRBoolean, sizeof(Boolean), X XtOffset(MenuPaneWidget, menuPane.ask_child), XtRString, "TRUE"}, X}; X XMenuPaneClassRec menuPaneClassRec = { X { X/* core_class fields */ X /* superclass */ (WidgetClass) &constraintClassRec, X /* class_name */ "MenuPane", X /* widget_size */ sizeof(MenuPaneRec), X /* class_initialize */ NULL, X /* class_part_initialize */ NULL, X /* class_inited */ FALSE, X /* initialize */ Initialize, X /* initialize_hook */ NULL, X /* realize */ Realize, X /* actions */ NULL, X /* num_actions */ 0, X /* resources */ resources, X /* num_resources */ XtNumber(resources), X /* xrm_class */ NULLQUARK, X /* compress_motion */ TRUE, X /* compress_exposure */ TRUE, X /* compress_enterleave */ TRUE, X /* visible_interest */ FALSE, X /* destroy */ NULL, X /* resize */ Resize, X /* expose */ XtInheritExpose, X /* set_values */ NULL, X /* set_values_hook */ NULL, X /* set_values_almost */ XtInheritSetValuesAlmost, X /* get_values_hook */ NULL, X /* accept_focus */ NULL, X /* version */ XtVersion, X /* callback_private */ NULL, X /* tm_table */ NULL, X /* query_geometry */ MenuPane_geometry X }, X { X/* composite_class fields */ X /* geometry_handler */ Geometry_handler, X /* change_managed */ Change_managed, X /* insert_child */ XtInheritInsertChild, X /* delete_child */ XtInheritDeleteChild, X /* move_focus_to_next */ NULL, /* remove these, somebody please! */ X /* move_focus_to_prev */ NULL X }, X { X/* constraint_class fields */ X /* resources */ NULL, X /* num_resources */ 0, X /* constraint_size */ sizeof(MPConstraintRecord), X /* initialize */ constraint_Initialize, X /* destroy */ NULL, X /* set_values */ NULL X }, X/* menuPane_class fields (NO NEW ONES) */ X}; X X/* class record */ X XWidgetClass menuPaneWidgetClass = (WidgetClass)&menuPaneClassRec; X X/**************************************************************** X * X * Standard Widget Procedures X * X ****************************************************************/ X X#define SIZE(mpw, cw) (mpw->menuPane.vert_pane ? cw->core.height : cw->core.width) X#define POSITION(mpw, cw) (mpw->menuPane.vert_pane ? cw->core.y : cw->core.x) X X/* > Initialize < */ X/* ARGSUSED */ Xstatic void XInitialize(request, new) XWidget request, new; X{ X MenuPaneWidget mpw = (MenuPaneWidget)new; X X /* inherit our parent's size if we are given one */ X if (mpw->core.width == 0) X mpw->core.width = XtParent(mpw)->core.width; X X if (mpw->core.height == 0) X mpw->core.height = XtParent(mpw)->core.height; X X /* save the old size, height or width for use by Resize() */ X mpw->menuPane.oldsize = SIZE(mpw, mpw); X} X X X/* ARGSUSED */ Xstatic void Xconstraint_Initialize(request, new) XWidget request, new; X{ X /* this child has yet to be managed */ X CONSTRAINTS_MANAGED(new) = FALSE; X} X X X/* > Resize < X * resize any children X */ Xstatic void Resize(w) XWidget w; X{ X MenuPaneWidget mpw = (MenuPaneWidget) w; X int Kids = 0; X int inc, bit, offset, round_up; X X#ifdef DEBUG X printf("Resize(menuPane)\n"); X#endif X if (mpw->composite.num_children == 0) X return; X X inc = SIZE(mpw, mpw) - mpw->menuPane.oldsize; X X mpw->menuPane.oldsize = SIZE(mpw, mpw); X X /* count the number of currently managed children */ X for (bit = 0; bit < mpw->composite.num_children; bit++) X if (CONSTRAINTS_MANAGED(mpw->composite.children[bit])) X Kids++; X X if (Kids == 0) X return; X X bit = inc / Kids; /* amount to resize each child by */ X round_up = inc - (bit * Kids); /* whats left after integer division */ X offset = 0; /* what to move the children along by */ X X#ifndef DEBUG X if (XtIsRealized(w)) X XtUnmapWidget(w); X#endif DEBUG X X /* resize kids */ X for (Kids = 0; Kids < mpw->composite.num_children; Kids++) X { X Widget kw = mpw->composite.children[Kids]; X X if (!CONSTRAINTS_MANAGED(kw)) X { X if (mpw->menuPane.vert_pane) X XtResizeWidget(kw, mpw->core.width, kw->core.height, X kw->core.border_width); X else X XtResizeWidget(kw, kw->core.width, mpw->core.height, X kw->core.border_width); X continue; X } X X if (mpw->menuPane.vert_pane) X { X XtResizeWidget(kw, mpw->core.width, X kw->core.height + round_up + bit, X kw->core.border_width); X XtMoveWidget(kw, kw->core.x, kw->core.y + offset); X } X else X { X XtResizeWidget(kw, X kw->core.width + round_up + bit, X mpw->core.height, X kw->core.border_width); X XtMoveWidget(kw, kw->core.x + offset, kw->core.y); X } X X offset += round_up + bit; X round_up = 0; X }; X X#ifndef DEBUG X if (XtIsRealized(w)) X XtMapWidget(w); X#endif DEBUG X} X X Xstatic void Realize(w, valueMask, attributes) XWidget w; XXtValueMask *valueMask; XXSetWindowAttributes *attributes; X{ X XtCreateWindow(w, InputOutput, (Visual *)CopyFromParent, (XtValueMask)*valueMask, attributes); X} X X X/* ARGSUSED */ Xstatic XtGeometryResult Geometry_handler(w, request, reply) XWidget w; XXtWidgetGeometry *request; XXtWidgetGeometry *reply; X{ X /* Any requests by the children are just refused, the parent X * knows best. X * If the resource XtNaskChild is set to TRUE then when a X * `change managed' event occurs the children are asked their preferred X * size. X */ X return(XtGeometryNo); X} X X Xstatic int preferred_size(mpw, use_constraints) XMenuPaneWidget mpw; XBoolean use_constraints; X{ X Widget cw = NULL; X int managed_size = 0; X Boolean is_managed; X Cardinal i; X X /* calculate the total height or width of the children */ X for (i = 0; i < mpw->composite.num_children; i++) X { X is_managed = use_constraints ? X CONSTRAINTS_MANAGED(mpw->composite.children[i]) X : XtIsManaged(mpw->composite.children[i]); X X if (is_managed) X { X cw = mpw->composite.children[i]; X managed_size += SIZE(mpw, cw) + cw->core.border_width; X } X } X X if ((managed_size == 0) || (cw == NULL)) X return (0); X X /* remove the last child's border width */ X managed_size -= cw->core.border_width; X return (managed_size); X} X X Xstatic int Xget_prev_pos(w, mpw) XWidget w; XMenuPaneWidget mpw; X{ X XtWidgetGeometry preferred_return; X X if (mpw->menuPane.ask_child) X { X (void)XtQueryGeometry(w, (XtWidgetGeometry *)NULL, X &preferred_return); X X if (mpw->menuPane.vert_pane) X return (preferred_return.height); X else X return (preferred_return.width); X } X return (SIZE(mpw, w)); X} X X Xstatic void Change_managed(w) XWidget w; X{ X MenuPaneWidget mpw = (MenuPaneWidget)w; X Cardinal i; X Widget cw = NULL; X int old_size = 0, new_size = 0, prev_pos = 0; X X#ifdef DEBUG X printf("Change_managed(menuPane, %s)\n",w->core.name); X#endif X X old_size = preferred_size(mpw, TRUE); X new_size = preferred_size(mpw, FALSE); X X /* change the space of the currently managed children to make X * room for the newly managed ones. X */ X if (old_size > 0 && old_size < new_size) X { X mpw->menuPane.oldsize = new_size; X Resize(w); X } X X prev_pos = - mpw->composite.children[0]->core.border_width; X X /* Move children to their right places. X * Children are placed one after the other, down or across, X * in the order that they we created. Their borders are overlapped X * so that only one border width separates two menu elements. X */ X for (i = 0; i < mpw->composite.num_children; i++) X { X cw = mpw->composite.children[i]; X X if (XtIsManaged(cw)) X { X if (mpw->menuPane.vert_pane) X XtMoveWidget(cw, -(cw->core.border_width), X prev_pos); X else X XtMoveWidget(cw, prev_pos, X -(cw->core.border_width)); X X prev_pos += get_prev_pos(cw, mpw) X + cw->core.border_width; X CONSTRAINTS_MANAGED(cw) = TRUE; X } X else X CONSTRAINTS_MANAGED(cw) = FALSE; X } X X X /* change the size of the currently managed children and make X * use up the space of the now unmanaged children. X */ X if (old_size > 0 && old_size > new_size) X { X mpw->menuPane.oldsize = new_size; X Resize(w); X } X X /* if the combined size of the children are smaller or larger than X * the menuPane parent then enlarge or shrink all the children to X * fit. We do this by faking a Resize event. X */ X new_size = preferred_size(mpw, TRUE); X if (SIZE(mpw, mpw) != new_size) X { X mpw->menuPane.oldsize = new_size; X Resize(w); X } X} X X X/* > MenuPane_geometry < X * return the preferred geometry for the menuPane widget X * The preferred geometry is the width/height of the menuPane and X * the combined height/width of the children. X */ Xstatic XtGeometryResult MenuPane_geometry(w, request, preferred_return) XWidget w; XXtWidgetGeometry *request; XXtWidgetGeometry *preferred_return; X{ X MenuPaneWidget mpw = (MenuPaneWidget)w; X X preferred_return->request_mode = CWWidth | CWHeight; X X if (mpw->menuPane.vert_pane) X { X preferred_return->height = preferred_size(mpw); X preferred_return->width = mpw->core.width; X } X else X { X preferred_return->height = mpw->core.height; X preferred_return->width = preferred_size(mpw); X } X X /* the size given the caller is not exactly what we want */ X if (((request->request_mode & CWWidth) && X (request->width != preferred_return->width)) || X ((request->request_mode & CWHeight) && X (request->height != preferred_return->height)) || X (preferred_return->request_mode != request->request_mode)) X return (XtGeometryAlmost); X X /* we are already the perfect size */ X if ((mpw->core.height == preferred_return->height) && X (mpw->core.width == preferred_return->width)) X return (XtGeometryNo); X X return (XtGeometryYes); X} END_OF_MenuPane.c if test 11055 -ne `wc -c <MenuPane.c`; then echo shar: \"MenuPane.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f MenuPane.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"MenuPane.h\" else echo shar: Extracting \"MenuPane.h\" \(1270 characters\) sed "s/^X//" >MenuPane.h <<'END_OF_MenuPane.h' X/* X * $Header: MenuPane.h,v 1.2 88/08/23 18:11:18 rlh2 Exp $ X */ X X/********************************************************************** X * MenuPaneWidget * X * (c) 1988 Richard Hesketh / rlh2@ukc.ac.uk * X * Computing Lab. University of Kent at Canterbury * X * * X * Subclass of constraintWidgetClass :looks after its children either * X * horizontally or vertically arranged * X ********************************************************************** X X This software is in the Public Domain and as such can be freely copied X and distributed provided this notice and the author's name is included. X*/ X X#ifndef _XtMenuPaneH_h X#define _XtMenuPaneH_h X/* X * New Resources/Parameters : X */ X X#define XtNvertPane "vertPane" X#define XtNaskChild "askChild" X X#define XtCVertpane "Vertpane" X#define XtCAskchild "Askchild" X X/* Class record pointer */ X Xextern WidgetClass menuPaneWidgetClass; X X/* Widget Type definition */ X Xtypedef struct _MenuPaneRec *MenuPaneWidget; Xtypedef struct _MenuPaneClassRec *MenuPaneWidgetClass; X X/*** PUBLIC ROUTINES defined in MenuPane Widget ***/ X/* NONE */ X X#endif _XtMenuPaneH_h END_OF_MenuPane.h if test 1270 -ne `wc -c <MenuPane.h`; then echo shar: \"MenuPane.h\" unpacked with wrong size! fi # end of overwriting check fi if test -f MenuPaneP.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"MenuPaneP.h\" else echo shar: Extracting \"MenuPaneP.h\" \(1957 characters\) sed "s/^X//" >MenuPaneP.h <<'END_OF_MenuPaneP.h' X/* X * $Header: MenuPaneP.h,v 1.2 88/08/23 18:10:46 rlh2 Exp $ X */ X X/********************************************************************** X * MenuPaneWidget * X * (c) 1988 Richard Hesketh / rlh2@ukc.ac.uk * X * Computing Lab. University of Kent at Canterbury * X * * X * Subclass of constraintWidgetClass :looks after its children either * X * horizontally or vertically arranged * X ********************************************************************** X X This software is in the Public Domain and as such can be freely copied X and distributed provided this notice and the author's name is included. X*/ X X#ifndef _XtMenuPanePrivate_h X#define _XtMenuPanePrivate_h X X#include "MenuPane.h" X Xstruct _mpconstraintpart { X Boolean managed_done; X}; X Xtypedef struct _mpconstraintpart MPConstraintPart; X Xstruct _mpconstraintrec { X MPConstraintPart menuPane; X}; X Xtypedef struct _mpconstraintrec MPConstraintRecord; Xtypedef MPConstraintRecord *MPConstraint; X X Xtypedef struct _menuPaneclasspart { X int mumble; /* no new fields */ X} MenuPaneClassPart; X X/* Full Class Record declaration */ X Xtypedef struct _MenuPaneClassRec { X CoreClassPart core_class; X CompositeClassPart composite_class; X ConstraintClassPart constraint_class; X MenuPaneClassPart menuPane_class; X} MenuPaneClassRec; X X/* Class record variable */ X Xextern MenuPaneClassRec menuPaneClassRec; X Xstruct _menuPanepart { X /* settable resources */ X Boolean vert_pane; /* TRUE if menu pane is vertical */ X Boolean ask_child; /* TRUE if child is asked its prefered size */ X X /* data derived from resources */ X int oldsize; X}; X Xtypedef struct _menuPanepart MenuPanePart; X Xtypedef struct _MenuPaneRec { X CorePart core; X CompositePart composite; X ConstraintPart constraint; X MenuPanePart menuPane; X} MenuPaneRec; X X#endif _XtMenuPanePrivate_h END_OF_MenuPaneP.h if test 1957 -ne `wc -c <MenuPaneP.h`; then echo shar: \"MenuPaneP.h\" unpacked with wrong size! fi # end of overwriting check fi if test -f README -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"README\" else echo shar: Extracting \"README\" \(1378 characters\) sed "s/^X//" >README <<'END_OF_README' XThere has been a few articles recently wondering about popup shells, menus Xand grabs. Well, I enclose a short test program which implements a popup Xmenu in the toolkit. The program will work as is on a VAX. However on a SUN Xdue to a bug in XtConvertStringToBoolean() in TMstate.c, it fails to pop Xdown the popup menu when the button is released. This problem can be fixed Xwith the context diff given in the enclosed file: TMstate.cdif X XAfter you have applied this patch the MenuPopup action will set the grab Xproperly so that all events will be propagated to the last spring loaded Xshell as well as the widget that they happened in. X XNow back to the example program. The program creates a single command button Xwithin a form. The translations of this button are set so that when the Xleft mouse button is pressed a shell widget is positioned relative Xto the button. This shell is then popped up revealing a menu of 4 command Xbuttons. With the left mouse button held down any of the 4 buttons can be Xchosen by moving in to them (this sets them in the foreground colour). XIf the button is released when it is inside any of the 4 menu buttons then Xthe callback of that particular button is called. The menu is then popped Xdown. If the button is released outside of any of the menu buttons then Xno callback is called and the menu is just popped down. X XRichard Hesketh Xrlh2@ukc.ac.uk END_OF_README if test 1378 -ne `wc -c <README`; then echo shar: \"README\" unpacked with wrong size! fi # end of overwriting check fi if test -f TMstate.cdif -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"TMstate.cdif\" else echo shar: Extracting \"TMstate.cdif\" \(507 characters\) sed "s/^X//" >TMstate.cdif <<'END_OF_TMstate.cdif' X*** ORIG/TMstate.c Fri Feb 26 17:48:55 1988 X--- TMstate.c Sat Aug 27 16:46:45 1988 X*************** X*** 1192,1198 **** X XtConvert((Widget) NULL, XtRString, &fromVal, XtRBoolean, &toVal); X if (toVal.addr == NULL) return FALSE; X X! *bP = (Boolean) *(int *)toVal.addr; X X return TRUE; X } X--- 1305,1311 ---- X XtConvert((Widget) NULL, XtRString, &fromVal, XtRBoolean, &toVal); X if (toVal.addr == NULL) return FALSE; X X! *bP = *(Boolean *)toVal.addr; X X return TRUE; X } END_OF_TMstate.cdif if test 507 -ne `wc -c <TMstate.cdif`; then echo shar: \"TMstate.cdif\" unpacked with wrong size! fi # end of overwriting check fi if test -f menutest.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"menutest.c\" else echo shar: Extracting \"menutest.c\" \(6741 characters\) sed "s/^X//" >menutest.c <<'END_OF_menutest.c' X/******************************************************************************* X * Very simple test program to show how popup menus are created in the toolkit * X * Richard Hesketh email: rlh2@ukc.ac.uk * X * Computing Lab. University of Kent at Canterbury, UK * X * * X * Permission to use, copy, modify, and distribute this program and * X * any documentation for any purpose and without fee is granted provided that * X * the authors name and this notice appears in all copies. The author accepts * X * no responsibility for the use of this program. * X *******************************************************************************/ X X#include <X11/Intrinsic.h> X#include <X11/StringDefs.h> X#include <X11/Command.h> X#include <X11/Form.h> X#include <X11/Shell.h> X X/* forward references to procedures */ Xvoid do_system(); Xvoid quit(); Xvoid set_popup(); X X/* widget hierarchy */ XWidget toplevel; XWidget layout; XWidget pb1; /* button who popups up the menu when pressed */ X XWidget popup_shell; /* shell of popup menu */ XWidget pop_layout; /* form widget of popup menu */ XWidget erik[4]; /* menu buttons */ X X/* translations for the button to popup the menu X * set_popup positions the shell. X * MenuPopup realizes the shell. X */ Xstatic String pb_Trans = X "<EnterWindow>: highlight() \n\ X <LeaveWindow>: unhighlight() \n\ X <Btn1Down>: set_popup(%s) MenuPopup(%s)"; X X/* translations for the command buttons of the popup menu X * the command callback is invoked when the button is released with X * the pointer in the command widget. X */ Xstatic String cb_Trans = X "<EnterWindow>: set() \n\ X <LeaveWindow>: unset() \n\ X <Btn1Up>: notify()"; X X/* translations for the shell of the popup menu. X * when the button is released the shell catches it and pops itself down. X */ Xstatic String pm_Trans = X "<Btn1Up>: MenuPopdown()"; X X/* new actions added by this program */ Xstatic XtActionsRec menu_actions[] = { X { "set_popup", set_popup }, X}; X X/* application routines !! */ Xstatic XtCallbackRec b_callbacks[] = { X { do_system, (caddr_t)NULL }, X { (XtCallbackProc)NULL, (caddr_t)NULL } X}; X X/* name of the shell, used by set_popup and MenuPopup actions */ Xstatic String popup_menu_name = "popup_menu"; X Xvoid Xmain(argc, argv) Xunsigned int argc; Xchar **argv; X{ X Arg args[6]; X Cardinal i = 0; X char ptrans[250]; X X /* initialize the toolkit and register the actions */ X i = 0; X toplevel = XtInitialize( "ademo", "Xademo", (ArgList)args, i, &argc, argv ); X XtSetArg(args[i], XtNwidth, 200); i++; X XtSetArg(args[i], XtNheight, 30); i++; X XtSetValues(toplevel, (ArgList)args, i); X X XtAddActions((XtActionList)menu_actions, XtNumber(menu_actions)); X X /* create the top button and its form parent */ X i = 0; X layout = XtCreateManagedWidget("layout", formWidgetClass, toplevel, X (ArgList)args, i); X X /* create the translations for the button which pops up the menu */ X /* we pass the name of the popup menu to both set_popup and MenuPopup */ X (void)sprintf(ptrans, pb_Trans, popup_menu_name, popup_menu_name); X i = 0; X XtSetArg(args[i], XtNwidth, 200); i++; X XtSetArg(args[i], XtNheight, 30); i++; X XtSetArg(args[i], XtNtranslations, XtParseTranslationTable(ptrans)); i++; X pb1 = XtCreateManagedWidget("button_to_popup_menu", commandWidgetClass, X layout, (ArgList)args, i); X X /* create the popup menu ... its shell, its layout widget and the menu X * buttons it holds. X */ X i = 0; X XtSetArg(args[i], XtNtranslations, XtParseTranslationTable(pm_Trans)); i++; X popup_shell = XtCreatePopupShell("popup_menu", overrideShellWidgetClass, X pb1, (ArgList)args, i); X X i = 0; X pop_layout = XtCreateManagedWidget("layout", formWidgetClass, popup_shell, X (ArgList)args, i); X X i = 0; X XtSetArg(args[i], XtNwidth, 110); i++; X XtSetArg(args[i], XtNheight, 29); i++; X X /* set the translations for the buttons of the menu. X * Set on window entry. Unset on window leave. X * Call the callback when button 1 is released. X */ X XtSetArg(args[i], XtNtranslations, XtParseTranslationTable(cb_Trans)); i++; X XtSetArg(args[i], XtNcallback, b_callbacks); i++; X X /* this button will give a listing of the current directory */ X XtSetArg(args[i], XtNlabel, "ls -la"); i++; X erik[0] = XtCreateManagedWidget("first_button", commandWidgetClass, X pop_layout, (ArgList)args, i); X X i = 6; X /* this button will print the name of the current directory */ X XtSetArg(args[4], XtNlabel, "pwd"); X XtSetArg(args[5], XtNfromVert, erik[0]); X erik[1] = XtCreateManagedWidget("second_button", commandWidgetClass, X pop_layout, (ArgList)args, i); X X i = 6; X /* this button will print `hello' */ X XtSetArg(args[4], XtNlabel, "echo \"hello\""); X XtSetArg(args[5], XtNfromVert, erik[1]); X erik[2] = XtCreateManagedWidget("third_button", commandWidgetClass, X pop_layout, (ArgList)args, i); X X i = 5; X /* this button quits the test program */ X XtSetArg(args[4], XtNlabel, "QUIT"); X XtSetArg(args[3], XtNfromVert, erik[2]); X erik[3] = XtCreateManagedWidget("fourth_button", commandWidgetClass, X pop_layout, (ArgList)args, i); X XtAddCallback(erik[3], XtNcallback, (caddr_t)quit); X X XtRealizeWidget(toplevel); X XtMainLoop(); X} X X X/* ARGSUSED */ Xvoid Xdo_system(w, client_data, call_data) XWidget w; Xcaddr_t client_data, call_data; /* unused */ X{ X String func_name; X Arg args[1]; X X /* simple application ... do the U*IX command named in the widget's label */ X XtSetArg(args[0], XtNlabel, &func_name); X XtGetValues(w, (ArgList)args, 1); X X system(func_name); X} X X X/* ARGSUSED */ Xvoid Xquit(w, client_data, call_data) XWidget w; /* unused */ Xcaddr_t client_data, call_data; /* unused */ X{ X exit(0); X} X X XWidget Xget_shell_from_name(name) XString name; X{ X if (strcmp(name, popup_menu_name) == 0) X return (popup_shell); X else X return (NULL); X} X X X/* ARGSUSED */ Xvoid Xset_popup(w, event, params, num_params) XWidget w; XXEvent *event; /* unused */ XString *params; XCardinal *num_params; X{ X /* position the menu, whose name was passed as the first and only X * parameter at position (20,5) relative to the Widget w. X */ X Widget a_shell; X int x, y; X Arg args[2]; X X if (*num_params != 1) X XtError("Wrong parameter count passed to set_popup()"); X X /* get the internal Widget id of the named shell */ X a_shell = get_shell_from_name(params[0]); X X if (a_shell == NULL) X XtError("Wrong shell name passed to set_popup()"); X X XtTranslateCoords(w, (Position)20, (Position)5, &x, &y); X X#ifndef SHELL_BUG_FIX X /* currently this is the only way to move created shells */ X XtMoveWidget(a_shell, x, y); X#else X /* use this when R3 fixes the shell bug */ X XtSetArg(args[0], XtNx, x); X XtSetArg(args[1], XtNy, y); X XtSetValues(a_shell, (ArgList)args, 2); X#endif SHELL_BUG_FIX X} END_OF_menutest.c if test 6741 -ne `wc -c <menutest.c`; then echo shar: \"menutest.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f panetest.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"panetest.c\" else echo shar: Extracting \"panetest.c\" \(2306 characters\) sed "s/^X//" >panetest.c <<'END_OF_panetest.c' X#include <X11/Intrinsic.h> X#include <X11/StringDefs.h> X#include <X11/Command.h> X#include "MenuPane.h" X XWidget toplevel, layout, fred[5], mPane1, erik[3], mPane2, john; X Xunmanage() X{ X XtUnmanageChild(mPane2); X} X Xmanage() X{ X XtManageChild(mPane2); X} X Xvoid main(argc, argv) X unsigned int argc; X char **argv; X{ X Arg args[4]; X Cardinal i = 0; X X i = 0; X toplevel = XtInitialize( "ademo", "Xademo", (ArgList)args, i, &argc, argv ); X XtSetArg(args[i], XtNwidth, 300); i++; X XtSetArg(args[i], XtNheight, 100); i++; X XtSetValues(toplevel, (ArgList)args, i); X X i = 0; X XtSetArg(args[i], XtNvertPane, FALSE); i++; X X layout = XtCreateManagedWidget("layout", menuPaneWidgetClass, toplevel, (ArgList)args, i); X X /* create a vertical pane with 5 children */ X i = 0; X XtSetArg(args[i], XtNwidth, 70); i++; X XtSetArg(args[i], XtNheight, 50); i++; X XtSetArg(args[i], XtNvertPane, TRUE); i++; X X mPane1 = XtCreateManagedWidget("MenuPane1", menuPaneWidgetClass, layout, (ArgList)args, i); X X i = 0; X fred[0] = XtCreateManagedWidget("A", commandWidgetClass, mPane1, (ArgList)args, i); X fred[1] = XtCreateManagedWidget("B", commandWidgetClass, mPane1, (ArgList)args, i); X fred[2] = XtCreateManagedWidget("C", commandWidgetClass, mPane1, (ArgList)args, i); X fred[3] = XtCreateManagedWidget("D", commandWidgetClass, mPane1, (ArgList)args, i); X fred[4] = XtCreateManagedWidget("E", commandWidgetClass, mPane1, (ArgList)args, i); X X /* create a horizontal pane with 3 children */ X i = 0; X XtSetArg(args[i], XtNwidth, 70); i++; X XtSetArg(args[i], XtNheight, 50); i++; X XtSetArg(args[i], XtNvertPane, FALSE); i++; X X mPane2 = XtCreateManagedWidget("MenuPane2", menuPaneWidgetClass, layout, (ArgList)args, i); X X i = 0; X erik[0] = XtCreateManagedWidget("1", commandWidgetClass, mPane2, (ArgList)args, i); X erik[1] = XtCreateManagedWidget("2", commandWidgetClass, mPane2, (ArgList)args, i); X erik[2] = XtCreateManagedWidget("3", commandWidgetClass, mPane2, (ArgList)args, i); X X i = 0; X john = XtCreateManagedWidget("A Pane Button", commandWidgetClass, layout, (ArgList)args, i); X X /* press "1" and see what happens */ X XtAddCallback(erik[0], XtNcallback, unmanage, (caddr_t)NULL); X X /* press "A Pane Button" and see what happens */ X XtAddCallback(john, XtNcallback, manage, (caddr_t)NULL); X X XtRealizeWidget(toplevel); X XtMainLoop(); X} END_OF_panetest.c if test 2306 -ne `wc -c <panetest.c`; then echo shar: \"panetest.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f patchlevel.h -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"patchlevel.h\" else echo shar: Extracting \"patchlevel.h\" \(21 characters\) sed "s/^X//" >patchlevel.h <<'END_OF_patchlevel.h' X#define PATCHLEVEL 0 END_OF_patchlevel.h if test 21 -ne `wc -c <patchlevel.h`; then echo shar: \"patchlevel.h\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 1 \(of 1\). cp /dev/null ark1isdone MISSING="" for I in 1 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 1 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mike Wexler(wyse!mikew) Phone: (408)433-1000 x1330