## popup-menu.api
#
# See bottom-of-file comments
# for an extended overview.
# Compiled by:
#
src/lib/x-kit/widget/xkit-widget.sublib# This api is implemented in:
#
#
src/lib/x-kit/widget/old/menu/popup-menu.pkgstipulate
include package threadkit; # threadkit is from
src/lib/src/lib/thread-kit/src/core-thread-kit/threadkit.pkg #
package xc = xclient; # xclient is from
src/lib/x-kit/xclient/xclient.pkg #
package g2d= geometry2d; # geometry2d is from
src/lib/std/2d/geometry2d.pkg #
package wg = widget; # widget is from
src/lib/x-kit/widget/old/basic/widget.pkgherein
api Popup_Menu {
Popup_Menu(X)
=
POPUP_MENU List( Popup_Menu_Item(X) )
also
Popup_Menu_Item(X)
#
= POPUP_MENU_ITEM (String, X)
| POPUP_SUBMENU (String, Popup_Menu(X))
;
# Return values by which the user-supplied
#
# attach_positioned_menu_to_widget
#
# callback function can communicate
# its menu-placement choice:
#
Popup_Menu_Position
#
= PUT_POPUP_MENU_UPPERLEFT_ON_SCREEN g2d::Point # Position the popup menu's upper-left corner at this screen coordinate.
| PUT_POPUP_MENU_ITEM_BENEATH_MOUSE Int
# Position the popu menu with mouse cursor centered over given item (0 is first item).
;
# Info from the MOUSE_FIRST_DOWN event
# triggering the menu pop-up:
#
Where_Info
=
WHERE_INFO
{ mouse_button: xc::Mousebutton,
window_point: g2d::Point,
screen_point: g2d::Point,
timestamp: xc::xserver_timestamp::Xserver_Timestamp
};
# Create unlabeled menu:
#
attach_menu_to_widget
:
( wg::Widget, # Parent widget for the menu.
List(xc::Mousebutton), # Pop up menu if any of these buttons are pressed.
Popup_Menu(X) # Menu to pop up.
)
->
( wg::Widget, # Resulting combined widget.
Mailop(X) # 'do_one_mailop' on this to get user menu selections.
);
# Same as above, except menu is labelled:
#
attach_labeled_menu_to_widget
:
( wg::Widget, # Parent widget for the menu.
List(xc::Mousebutton), # Pop up menu if any of these buttons are pressed.
String, # Label for menu.
Popup_Menu(X) # Menu to pop up.
)
->
( wg::Widget, # Resulting combined widget.
Mailop(X) # 'do_one_mailop' on this to get user menu selections.
);
# Same as attach_menu_to_widget except menu
# placement is specified:
#
attach_positioned_menu_to_widget
:
( wg::Widget, # Parent widget for the menu.
List(xc::Mousebutton), # Pop up menu if any of these buttons are pressed.
Popup_Menu(X), # Menu to pop up.
Where_Info -> Popup_Menu_Position # User function to position the menu at pop-up time.
)
->
( wg::Widget, # Resulting combined widget.
Mailop(X) # 'do_one_mailop' on this to get user menu selections.
);
# A lower-level call allowing finer control:
#
make_lowlevel_popup_menu
:
( wg::Root_Window,
Popup_Menu(X),
Null_Or(String)
)
->
( xc::Mousebutton,
Popup_Menu_Position,
g2d::Point,
Mailop( xc::Envelope(xc::Mouse_Mail))
)
->
Mailop( Null_Or(X) );
};
end;
# OVERVIEW:
#
# The x-kit widgets currently provide a simple form
# of pop-up menu support in the popup_menu package.
#
# A MENU value specifies the structure of a menu
# and the value associated with each entry.
#
# The SUBMENU constructor is used for defining
# hierarchical menus. The menu remains displayed
# and active as long as some mouse button is depressed.
# The user's choice corresponds to the item under the
# mouse cursor when the last mouse button is released.
#
# One a menu has been defined, there are various ways
# it can be used.
#
# The simplest way is to attach it to a widget
# using one of the two attach functions:
#
# attach_menu_to_widget # For menus without labels.
# attach_labelled_menu # If a label is desired.
#
# The result of attaching a menu to a widget is a
# new widget and a mailop that provides the user's
# menu choices.
#
# When attaching a menu to a widget, the programmer
# specifies the mouse button that is to pop up the menu.
# When the user presses the specified mouse button
# while the cursor is over the widget to which the
# menu is attached, the menu pops up.
# Any other mouse button press events, and all
# other mouse events, are passed on to the underlying
# widget.
# If the user selects a menu item, then the
# associated value is reported through the mailop.
# If the user does not select an item, nothing is
# reported.
#
# attach_positioned_menu_to_widget
# Same as attach_menu_to_widget, but provides control
# over menu placement. In particular, it can be
# used to implement menu buttons.
# When a mouse button press triggers
# the display of the menu, the user-supplied
# callback function is invoked with a value
# of type Where_Info, containing the information
# supplied by the MOUSE_FIRST_DOWN event # MOUSE_FIRST_DOWN def in
src/lib/x-kit/xclient/src/window/widget-cable-old.pkg# corresponding to the button press.
# The callback returns a Popup_Menu_Position
# value specifying its choice of menu position,
# which is honored so long as it allows the
# complete popup menu to appear on-screen.
#
# make_lowlevel_popup_menu:
# At times the above high-level popup menu
# interfaces do not provide enough control.
#
# This function takes a Root_Window, a Popup_Menu,
# and an optional string and returns a function
# which pops up the given menu on the given display.
#
# To use the popup fn a thread waits for some
# mouseclick and then calls the popup fn with
#
# ( clicked_button, # Mousebutton that activated the popup menu.
# desired_popup_menu_position, # Where onscreen to position the popup menu.
# mouseclick_position, # Position onscreen of clicked_button.
# from_mouse' # Mailop yielding the mouse events.
# )
#
# The popup fn returns a popup_menu_result'
# mailop which yields NULL if the user
# made no selection, otherwise THE selection.
#
# The calling thread should not read from
# from_mouse' while the popup fn is running.
#
# One package which uses this call:
#
#
src/lib/x-kit/widget/old/fancy/graphviz/graphviz-widget.pkg#
# Credit: The above comments are adapted from
# p36-37 of Gansner+Reppy's 1993 eXene widget manual,
# http://mythryl.org/pub/exene/1993-widgets.ps
## COPYRIGHT (c) 1991 by AT&T Bell Laboratories See SMLNJ-COPYRIGHT file for details.
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.