(3)

NAME
XfwfPullDown

DESCRIPTION
A PullDown button looks like a normal button, but when it is clicked or pressed, a menu drops down. The menu can be specified in two ways: as a string or as a widget. If a string is given, it must be in the correct syntax for the EzMenu(3) widget and a widget will be created automatically. If a widget is given instead, it must be a widget that is able to pop up: in other words: a Shell widget or a subclass of Shell. The most likely application of this widget is as a menu in a menu bar. A menu bar can be created, e.g., with a RowCol widget and a number of PullDown buttons. By default, the activate that is inherited from Button is still called, but as soon as the button is first pressed, not only after a click. Most applications will not need this callback.

  Public variables
XfwfPullDown
Name | Class | Type | Default
XtNpopup | XtCPopup | Widget | NULL
XtNmenu | XtCMenu | String | NULL
XtNhotkey | XtCHotkey | String | NULL
XtNmenuCursor | XtCMenuCursor | Cursor | "arrow"

XtNpopup
    Two resources determine the menu. The popup resource can be pointed at the widget that should pop up when the button is pressed, but when the popup resource is NULL, the menu will be created >from the menu resource. If the popup resource is set, it must be set to a widget that is (a subclass of) a Shell widget.

    Widget  popup = NULL

XtNmenu
    When popup is NULL, the widget will be created from the textual description in menu. For the syntax of this string, see the EzMenu(3).

    String  menu = NULL

XtNhotkey
    The pull down button installs an event handler that catches all keyboard events for the whole application and checks for a special key combination. If that key is detected, the menu will be popped up. Thus, the menu can be used even if the keyboard focus is somewhere else. The hotkey resource is usually a string such as "Alt<Key>a", or "Ctrl<Key>f". When the hotkey resource is used, any accelerators will be ignored.

    String  hotkey = NULL

XtNmenuCursor
    The cursor shape that is used in the menu can be set with the menuCursor resource. By default it is an arrow pointing to the upper right.

    Cursor  menuCursor = <String>"arrow"

XtNframeWidth
    Since the most likely place for this type of button will be in a menubar, the default frame width is reset to zero.

     frameWidth = 0

XtNshrinkToFit
    The shrinkToFit resource is set to a new default of True.

     shrinkToFit = True
    XfwfButton
    Name | Class | Type | Default
    XtNactivate | XtCActivate | Callback | NULL
    XfwfLabel
    Name | Class | Type | Default
    XtNlabel | XtCLabel | String | NULL
    XtNfont | XtCFont | FontStruct | XtDefaultFont
    XtNforeground | XtCForeground | Pixel | XtDefaultForeground
    XtNalignment | XtCAlignment | Alignment | 0
    XtNmargin | XtCMargin | Int | 2
    XtNshrinkToFit | XtCShrinkToFit | Boolean | False
    XtNrvStart | XtCRvStart | Int | 0
    XtNrvLength | XtCRvLength | Int | 0
    XfwfBoard
    Name | Class | Type | Default
    XtNabs_x | XtCAbs_x | Int | 0
    XtNrel_x | XtCRel_x | Float | "0.0"
    XtNabs_y | XtCAbs_y | Int | 0
    XtNrel_y | XtCRel_y | Float | "0.0"
    XtNabs_width | XtCAbs_width | Int | 0
    XtNrel_width | XtCRel_width | Float | "1.0"
    XtNabs_height | XtCAbs_height | Int | 0
    XtNrel_height | XtCRel_height | Float | "1.0"
    XtNhunit | XtCHunit | Float | "1.0"
    XtNvunit | XtCVunit | Float | "1.0"
    XtNlocation | XtCLocation | String | NULL
    XfwfFrame
    Name | Class | Type | Default
    XtNcursor | XtCCursor | Cursor | None
    XtNframeType | XtCFrameType | FrameType | XfwfRaised
    XtNframeWidth | XtCFrameWidth | Dimension | 0
    XtNframeOffset | XtCFrameOffset | Dimension | 0
    XtNshadowScheme | XtCShadowScheme | ShadowScheme | XfwfAuto
    XtNlightColor | XtCLightColor | Pixel | XtDefaultBackground
    XtNdarkColor | XtCDarkColor | Pixel | XtDefaultForeground
    XtNlightStipple | XtCLightStipple | Bitmap | NULL
    XtNdarkStipple | XtCDarkStipple | Bitmap | NULL
    XfwfCommon
    Name | Class | Type | Default
    XtNtraversalOn | XtCTraversalOn | Boolean | True
    XtNhighlightThickness | XtCHighlightThickness | Dimension | 2
    XtNhighlightColor | XtCHighlightColor | Pixel | XtDefaultForeground
    XtNhighlightPixmap | XtCHighlightPixmap | Pixmap | None
    XtNnextTop | XtCNextTop | Callback | NULL
    XtNuserData | XtCUserData | Pointer | NULL
    Composite
    Name | Class | Type | Default
    XtNchildren | XtCChildren | WidgetList | NULL
    insertPosition | XtCInsertPosition | XTOrderProc | NULL
    numChildren | XtCNumChildren | Cardinal | 0
    Core
    Name | Class | Type | Default
    XtNx | XtCX | Position | 0
    XtNy | XtCY | Position | 0
    XtNwidth | XtCWidth | Dimension | 0
    XtNheight | XtCHeight | Dimension | 0
    borderWidth | XtCBorderWidth | Dimension | 0
    XtNcolormap | XtCColormap | Colormap | NULL
    XtNdepth | XtCDepth | Int | 0
    destroyCallback | XtCDestroyCallback | XTCallbackList | NULL
    XtNsensitive | XtCSensitive | Boolean | True
    XtNtranslations | XtCTranslations | XTTranslations | NULL
    ancestorSensitive | XtCAncestorSensitive | Boolean | False
    accelerators | XtCAccelerators | XTTranslations | NULL
    borderColor | XtCBorderColor | Pixel | 0
    borderPixmap | XtCBorderPixmap | Pixmap | NULL
    background | XtCBackground | Pixel | 0
    backgroundPixmap | XtCBackgroundPixmap | Pixmap | NULL
    mappedWhenManaged | XtCMappedWhenManaged | Boolean | True
    XtNscreen | XtCScreen | Screen * | NULL

  Translations
<Btn1Down>: open_menu()
Button1<Enter>: open_menu()
<Key>Return: open_menu()

  Actions

note
    note is for debugging only.
    void note($, XEvent* event, String* params, Cardinal* num_params)
    {
        static String Xeventname[] = {
    	"", "", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease",
    	"MotionNotify", "EnterNotify", "LeaveNotify", "FocusIn",
    	"FocusOut", "KeymapNotify", "Expose", "GraphicsExpose",
    	"NoExpose", "VisisbilityNotify", "CreateNotify", "DestroyNotify",
    	"UnmapNotify", "MapNotify", "MapRequest", "ReparentNotify",
    	"ConfigureNotify", "ConfigureRequest", "GravityNotify",
    	"ResizeRequest", "CirculateNotify", "CirculateRequest",
    	"PropertyNotify", "SelectionClear", "SelectionRequest",
    	"SelectionNotify", "ColormapNotify", "ClientMessage",
    	"MappingNotify", };
        (void) fprintf(stderr, "%s received %s\n",
    		   XtName($), Xeventname[event->type]);
    }

open_menu
    The open_menu action computes the coordinates of the menu, such that it will appear directly below the button. It pops up the menu and calls the activate routines.
    void open_menu($, XEvent* event, String* params, Cardinal* num_params)
    {
        Position x, y;
        if ($popup == NULL) return;
        XtTranslateCoords($, 0, $height, x, y);
        XtMoveWidget($popup, x, y);
        XtPopupSpringLoaded($popup);
        XtGrabPointer($popup, True, EnterWindowMask | LeaveWindowMask |
    		  ButtonPressMask | ButtonReleaseMask, GrabModeAsync,
    		  GrabModeAsync, None, $cursor, CurrentTime);
        XtCallCallbackList($, $activate, event);
    }

Importss
incl
 <Xfwf/EzMenu.h>
incl
 <stdio.h>

  Methods
Both the initialize and set_values methods need to create a new menu widget, if the menu resource is set and the popup resource is not. A utility function is used to do the actual work. If both popup and menu are set, popup is used and menu is ignored.
initialize(Widget  request, $, ArgList  args, Cardinal * num_args)
{
    if ($popup == NULL  $menu != NULL) create_menu($);
    if ($popup != NULL  $hotkey != NULL) create_accelerator($);
}
set_values is similar. Changes in these resources never cause a redraw, so the method always returns False.
Boolean  set_values(Widget  old, Widget  request, $, ArgList  args, Cardinal * num_args)
{
    if ($old$popup != $popup)
	XtDestroyWidget($old$popup);
    else if ($old$menu != $menu)
	create_menu($);
    if ($old$menuCursor != $menuCursor)
	if ($popup) XtVaSetValues($popup, XtNcursor, $menuCursor, NULL);
    if ($old$hotkey != $hotkey)
	create_accelerator($);
    return False;
}

Utilities
The create_menu routine is used to create an instance of an EzMenu (pronounced `e-ZEE-menu', an easy-to-use version of the Athena simple menu).
create_menu($)
{
    if ($popup) XtDestroyWidget($popup);
    $popup = XtVaCreatePopupShell("_menu", xfwfEzMenuWidgetClass, $,
				  XtNmenu, $menu, XtNcursor, $menuCursor,
				  NULL);
}
create_accelerator takes the hotkey and expands it into a correct accelerators resource.
create_accelerator($)
{
    char s[100];
    XtAccelerators a;
    (void) strcpy(s, $hotkey);
    (void) strcat(s, ": open_menu()");
    a = XtParseAcceleratorTable(s);
    XtVaSetValues($, XtNaccelerators, a, NULL);
}