home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / lib / Xaw / MenuButton.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-22  |  6.5 KB  |  214 lines

  1. /* $XConsortium: MenuButton.c,v 1.18 91/06/22 18:03:46 rws Exp $ */
  2.  
  3. /*
  4.  * Copyright 1989 Massachusetts Institute of Technology
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appear in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of M.I.T. not be used in advertising or
  11.  * publicity pertaining to distribution of the software without specific,
  12.  * written prior permission.  M.I.T. makes no representations about the
  13.  * suitability of this software for any purpose.  It is provided "as is"
  14.  * without express or implied warranty.
  15.  *
  16.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  17.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  18.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  19.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  20.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
  21.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  22.  *
  23.  */
  24.  
  25.  
  26. /***********************************************************************
  27.  *
  28.  * MenuButton Widget
  29.  *
  30.  ***********************************************************************/
  31.  
  32. /*
  33.  * MenuButton.c - Source code for MenuButton widget.
  34.  *
  35.  * This is the source code for the Athena MenuButton widget.
  36.  * It is intended to provide an easy method of activating pulldown menus.
  37.  *
  38.  * Date:    May 2, 1989
  39.  *
  40.  * By:      Chris D. Peterson
  41.  *          MIT X Consortium 
  42.  *          kit@expo.lcs.mit.edu
  43.  */
  44.  
  45. #include <stdio.h>
  46. #include <X11/IntrinsicP.h>
  47. #include <X11/StringDefs.h>
  48.  
  49. #include <X11/Xaw/XawInit.h>
  50. #include <X11/Xaw/MenuButtoP.h>
  51.  
  52. static void ClassInitialize();
  53. static void PopupMenu();
  54.  
  55. #define superclass ((CommandWidgetClass)&commandClassRec)
  56.  
  57. static char defaultTranslations[] = 
  58.     "<EnterWindow>:     highlight()             \n\
  59.      <LeaveWindow>:     reset()                 \n\
  60.      <BtnDown>:         reset() PopupMenu()     ";
  61.  
  62. /****************************************************************
  63.  *
  64.  * Full class record constant
  65.  *
  66.  ****************************************************************/
  67.  
  68. /* Private Data */
  69.  
  70. #define offset(field) XtOffsetOf(MenuButtonRec, field)
  71. static XtResource resources[] = {
  72.   {
  73.     XtNmenuName, XtCMenuName, XtRString, sizeof(String), 
  74.     offset(menu_button.menu_name), XtRString, (XtPointer)"menu"},
  75. };
  76. #undef offset
  77.  
  78. static XtActionsRec actionsList[] =
  79. {
  80.   {"PopupMenu",    PopupMenu}
  81. };
  82.  
  83. MenuButtonClassRec menuButtonClassRec = {
  84.   {
  85.     (WidgetClass) superclass,        /* superclass          */    
  86.     "MenuButton",            /* class_name          */
  87.     sizeof(MenuButtonRec),           /* size              */
  88.     ClassInitialize,            /* class_initialize      */
  89.     NULL,                /* class_part_initialize  */
  90.     FALSE,                /* class_inited          */
  91.     NULL,                /* initialize          */
  92.     NULL,                /* initialize_hook      */
  93.     XtInheritRealize,            /* realize          */
  94.     actionsList,            /* actions          */
  95.     XtNumber(actionsList),        /* num_actions          */
  96.     resources,                /* resources          */
  97.     XtNumber(resources),        /* resource_count      */
  98.     NULLQUARK,                /* xrm_class          */
  99.     FALSE,                /* compress_motion      */
  100.     TRUE,                /* compress_exposure      */
  101.     TRUE,                /* compress_enterleave    */
  102.     FALSE,                /* visible_interest      */
  103.     NULL,                /* destroy          */
  104.     XtInheritResize,            /* resize          */
  105.     XtInheritExpose,            /* expose          */
  106.     NULL,                /* set_values          */
  107.     NULL,                /* set_values_hook      */
  108.     XtInheritSetValuesAlmost,        /* set_values_almost      */
  109.     NULL,                /* get_values_hook      */
  110.     NULL,                /* accept_focus          */
  111.     XtVersion,                /* version          */
  112.     NULL,                /* callback_private      */
  113.     defaultTranslations,                   /* tm_table          */
  114.     XtInheritQueryGeometry,        /* query_geometry      */
  115.     XtInheritDisplayAccelerator,    /* display_accelerator      */
  116.     NULL                /* extension          */
  117.   },  /* CoreClass fields initialization */
  118.   {
  119.     XtInheritChangeSensitive        /* change_sensitive      */ 
  120.   },  /* SimpleClass fields initialization */
  121.   {
  122.     0,                                     /* field not used    */
  123.   },  /* LabelClass fields initialization */
  124.   {
  125.     0,                                     /* field not used    */
  126.   },  /* CommandClass fields initialization */
  127.   {
  128.     0,                                     /* field not used    */
  129.   },  /* MenuButtonClass fields initialization */
  130. };
  131.  
  132.   /* for public consumption */
  133. WidgetClass menuButtonWidgetClass = (WidgetClass) &menuButtonClassRec;
  134.  
  135. /****************************************************************
  136.  *
  137.  * Private Procedures
  138.  *
  139.  ****************************************************************/
  140.  
  141. static void ClassInitialize()
  142. {
  143.     XawInitializeWidgetSet();
  144.     XtRegisterGrabAction(PopupMenu, True, ButtonPressMask | ButtonReleaseMask,
  145.              GrabModeAsync, GrabModeAsync);
  146. }
  147.  
  148. /* ARGSUSED */
  149. static void
  150. PopupMenu(w, event, params, num_params)
  151. Widget w;
  152. XEvent * event;
  153. String * params;
  154. Cardinal * num_params;
  155. {
  156.   MenuButtonWidget mbw = (MenuButtonWidget) w;
  157.   Widget menu, temp;
  158.   Arg arglist[2];
  159.   Cardinal num_args;
  160.   int menu_x, menu_y, menu_width, menu_height, button_height;
  161.   Position button_x, button_y;
  162.  
  163.   temp = w;
  164.   while(temp != NULL) {
  165.     menu = XtNameToWidget(temp, mbw->menu_button.menu_name);
  166.     if (menu == NULL) 
  167.       temp = XtParent(temp);
  168.     else
  169.       break;
  170.   }
  171.  
  172.   if (menu == NULL) {
  173.     char error_buf[BUFSIZ];
  174.     sprintf(error_buf, "MenuButton: %s %s.",
  175.         "Could not find menu widget named", mbw->menu_button.menu_name);
  176.     XtAppWarning(XtWidgetToApplicationContext(w), error_buf);
  177.     return;
  178.   }
  179.   if (!XtIsRealized(menu))
  180.     XtRealizeWidget(menu);
  181.   
  182.   menu_width = menu->core.width + 2 * menu->core.border_width;
  183.   button_height = w->core.height + 2 * w->core.border_width;
  184.   menu_height = menu->core.height + 2 * menu->core.border_width;
  185.  
  186.   XtTranslateCoords(w, 0, 0, &button_x, &button_y);
  187.   menu_x = button_x;
  188.   menu_y = button_y + button_height;
  189.  
  190.   if (menu_x >= 0) {
  191.     int scr_width = WidthOfScreen(XtScreen(menu));
  192.     if (menu_x + menu_width > scr_width)
  193.       menu_x = scr_width - menu_width;
  194.   }
  195.   if (menu_x < 0) 
  196.     menu_x = 0;
  197.  
  198.   if (menu_y >= 0) {
  199.     int scr_height = HeightOfScreen(XtScreen(menu));
  200.     if (menu_y + menu_height > scr_height)
  201.       menu_y = scr_height - menu_height;
  202.   }
  203.   if (menu_y < 0)
  204.     menu_y = 0;
  205.  
  206.   num_args = 0;
  207.   XtSetArg(arglist[num_args], XtNx, menu_x); num_args++;
  208.   XtSetArg(arglist[num_args], XtNy, menu_y); num_args++;
  209.   XtSetValues(menu, arglist, num_args);
  210.  
  211.   XtPopupSpringLoaded(menu);
  212. }
  213.  
  214.