1.96 class menu

A Menu is a dialog item that allows the user the select one or more values from a list. In its functionality it is similar to a list_browser object. However, a list_browser is meant to select from a dynamically generated list that may be large, while a menu is meant to select from a small number of alternatives that is generally static.

Two independent properties define a menu. menu->kind defines how the items are presented: as a drop-down combo box showing the selection (cycle), as a list of items with a radio button or check box (marked), or as a segmented control (choice). menu->multiple_selection defines whether the user may select one or more items. menu->kind resets menu->multiple_selection to @off, so set the kind first. toggle is a shorthand for a marked menu with multiple selection:

?- new(M, menu(options, toggle)).
?- new(M, menu(options, marked)), send(M, multiple_selection, @on).

Menus are drawn in the colours of the theme; see the class variables accent_colour, indicator_border, indicator_background, indicator_size, segment_background, segment_border and segment_pressed.

marked and choice menus accept the keyboard focus. The arrow keys move the selection of a single selection menu. In a multiple selection menu they move menu<-focus_item, which Space or Return toggles. At the first or last item, Left and Right move the focus to the previous or next dialog item.

1.96.1 Message forwarding

1.96.2 Menu layout

A menu consists of a label and a list of items. The label is placed in a box described by the area menu<-label_area. The items are placed in a two-dimensional array, each in its own box. These item boxes all have the same size (menu<-item_size). The top-left-corner of the first item is at menu<-item_offset.

If menu<->layout equals horizontal, the items are placed left-to-right. If menu<->layout equals vertical, the items are placed top-to-bottom. The items are spread over menu<-columns columns. In both layouts the label is left of the first item, so a dialog aligns it with the labels of the items above and below. The following illustrates the placement of a menu with horizontal layout, 2 columns and 5 items:

label   item-1   item-2   item-3
        item-4   item-5

Various parameters influence the final layout. menu<->gap defines the horizontal and vertical space between the items and menu<->border defines the white space between the item and the box around it.

See also
- menu->initialise
- menu_item-message
- menu-columns
- menu->kind
- dialog_item-auto_value_align
- class menu_item
- class popup

1.96.3 Instance variables

menu <- accelerator_font: font=font*
Font in which keyboard accelerators are annotated. When @nil, possible accelerators are not annotated. Used by class popup.
menu <- border: width=0..
Border (in pixels) between the item and its box if graphical<-pen is not zero. When graphical<-pen equals 0, border is only an additional gap.
See also
- menu->border
- menu-gap
menu <- columns: number=1..
Number of columns over which the menu-items are spread. See the class documentation for details.

Defaults: The default is 1

See also
- menu-layout
- class menu
menu-default: value=any|chain|function*
Initial value as well as the value to which the menu<-selection is restored by menu->restore. If the menu has menu<-multiple_selection: @off this is a single value, otherwise it is a chain of values.

The default value may also be a function object. In this case menu->restore evaluates this function and uses the result to set the menu<-selection.

menu <- feedback: feedback={box,image,show_selection_only}
Old name for the presentation, kept for compatibility. Sending menu->feedback sets menu->kind, keeping menu->multiple_selection:
show_selection_only
menu->kind
box
menu->kind
image
menu->kind
See also
menu-kind
menu-focus_item: item=menu_item
The item operated by the keyboard: the item with the focus ring. Defaults to the (first) selected item or else the first active item. Set it with menu->focus_item.
menu <- format: alignment={left,center,right}
The layout of menu_items in a menu is a 1 or 2 dimensional table. The menu will first determine the number and size of the rectangular cells in this table. This parameter determines how the items are aligned in their cell.
See also
text-format
menu <- gap: size
Amount of white space between the items in both X- and Y-direction. Note that the menu<->border is between the item and its surrounding box, while menu<->gap defines the distance between the surrounding boxes of adjacent items.
See also
menu-border
menu <- item_offset: offset=point
Offset in pixels of the first item, relative to the origin of the menu. Normally not useful for application programmers.
See also
- menu-label_area
- menu-item_size
menu <- item_size: size=size
Size of the box in which each item is formatted. An item at location (X,Y) is located at x-pixel location:
Menu?x + Menu?item_offset?x +
X*(Menu?item_size?w + Menu?gap?w).

and similar for the y-coordinate.

See also
- menu-label_area
- menu-item_offset
menu-kind: kind={cycle,marked,choice,toggle,popup}
How the items are presented. Yields toggle for a marked menu with menu<-multiple_selection @on.
See also
- menu->initialise
- menu->kind
- menu-feedback
menu <- label_area: area=area*
Pixel area relative to the origin of the menu for formatting the label. Only applicable if menu<->show_label equals @on.
See also
- menu-item_size
- menu-item_offset
dialog_item <- label_font: font*
Font used to format the label. Only applicable if menu<-show_label equals @on.
menu <- layout: orientation={horizontal,vertical}
Determines whether subsequent items are places left-to-right (horizontal) or top-to-bottom (vertical). If menu<-columns is greater than 1 and layout is horizontal, the items are placed in horizontal rows. If layout is vertical, the items are placed in vertical columns.
See also
menu-columns
menu <- left_offset: offset=0..
Left margin between the item-box and the item itself. Used to reserve space for the radio buttons, check boxes or images of a marked menu and for the padding of the segments of a choice menu.
menu <- members: items=chain
Chain of menu-items that are part of the menu.
See also
- menu_item-menu
- menu->append
menu <- multiple_selection: multiple=bool
If @on, any item can be either selected or deselected. It @off, exactly one item has status menu_item<->selected. A marked menu shows radio buttons if @off and check boxes if @on. A cycle menu always has a single selection.

If @on, Alt-click or double-click on an item selects only this item. Doing so again on this item while it is the only one selected restores the selection from before. The message of the menu is called as for a click on the item.

See also
menu_item-selected
menu <- off_image: image=image|{marked}*
Image painted in front of items of a marked menu that have MenuItem<->selected: @off. When marked (default), this is a radio button or check box drawn in the theme colours. When @nil, nothing is painted before the item.
See also
menu-on_image
menu <- on_image: image=image|{marked}*
Image painted in front of items of a marked menu that have MenuItem<->selected: @on. When marked (default), this is a radio button or check box drawn in the theme colours; in a popup it is a check mark. When @nil, nothing is painted before the item.
See also
menu-off_image
menu <- preview: item=menu_item*
Menu_item in the preview state: the item under the pointer of an open popup or the item of a menu that is being pressed.
See also
menu-preview_feedback
menu <-> preview_feedback: feedback={box,rounded_box,inverted_rounded_box,invert,colour}
Visual feedback used to indicate the item that is in the preview state. Possible values:
box
Draw a box around the item (like menu->feedback)
invert
Invert the box in which the item is formatted. Similar to menu->feedback, but the latter only inverts the item.
See also
menu-preview
menu <- right_offset: offset=0..
Right-margin between the item and its surrounding box. Its value is 0 if there is no item in the menu that has a dialog_item<->popup. Otherwise it is the width of the pullright marker plus menu<-border.
menu <- show_label: show=bool
If @on, the label is formatted in dialog_item<-label_font in the box determined by menu<-label_area. Otherwise the label is invisible.
menu <- value_font: font=font
Default font used to display the text of the items. This font may be overruled for an individual item using menu_item<->font. The latter is often used for font-selectors to display each item in the font that will be selected.
See also
- menu_item-font
- menu_item->font
menu <- value_width: width=0..
Minimum width used for the value. It is used for two purposes:

1.96.4 Send methods

menu ->_changed_item: changed=menu_item
Internal method to deal with changed items. When a menu-item is changed directly, it will send __changed_item_ to its menu.
menu ->active_all_items: active=bool
If @on, all items will be made active; otherwise all items will be made inactive.
See also
- menu->all_off
- menu_item-active
- menu->update
menu ->active_item: item=member:menu_item, active=bool
(De) activate a single item indicated by object. Object is either a menu_item or the value of a menu_item. Example:
?- new(M, menu(fill, marked)),
   send_list(M, append,
                         [ @nil,
                           @grey12_image,
                           @grey25_image
                         ]),
   send(M, active_item, @grey12_image, @off).
See also
- menu<-active_item
- menu->update
menu ->all_off:
Equivalent to
send(Menu, active_all_items, @off).

Available for backward compatibility.

See also
- menu->all_on
- menu->active_all_items
menu ->all_on:
Equivalent to
send(Menu, active_all_items, @on).

Available for backward compatibility.

See also
menu->all_off
menu ->append: item=menu_item
Append a menu-item to the menu. The appended item will always be the last. Note that class menu_item defines a conversion function that converts popups (for pullright menu's) and values into menu_items.

For popup objects, if the argument is the name gap, the last added item is sent menu_item->end_group. This inserts a group-separation line in the menu.

See also menu->members, menu->insert_before and send_list/3.

See also
- menu->prepend
- menu_item<-convert
- menu-members
menu ->apply: always=[bool]
If menu<-modified yields @on or always equals @on and menu<-selection succeeds, dialog_item<-message is forwarded with the following arguments:
@receiver the menu
@arg1 menu<-selection.

See also dialog->apply.

menu ->border: width=0..
@see menu-border
menu ->clear:
Delete all items from the menu.
menu ->clear_selection:
Deselect all items. See also menu->selection.
See also
menu->selection
menu ->compute:
menu->compute recalculates various variables to speed-up redraw. These are menu<-label_area, menu<-item_offset, menu<-item_size, menu<-left_offset and menu<-right_offset.
menu ->delete: item=member:menu_item
Delete a menu_item or the menu_item that has the same menu<->value as the argument from the menu. Note that it is generally bad style to change the contents of menu's. Normally items that should not be activated in some context are made inactive.
menu ->event: event
First tries dialog_item->event. On failure it passes the event of @_button_gesture if graphical<-active equals @on. The real work is done by menu->execute.
See also
- menu<-item_from_event
- menu->execute
menu ->execute: event=[event]
Execution of a menu implies setting the selection and -if there is a message to execute-, execute this message. The exact behaviour is determined by various style parameter:
menu <-feedback: ->
equals show_selection_only Select the next item
menu <-multiple_selection: ->
== @on Toggle the graphical<->selected attribute of the item on which the event occurred.
menu <-multiple_selection: ->
== @off Make the selection of the menu the item on which the event occurred.
See also
menu->event

menu ->initialise: name=[name], kind=[name], message=[code]*
Create from its dialog_item->label, menu->kind and dialog_item->message. See class menu for details.

Defaults: The default dialog_item->label is the classname of the menu (menu). The default menu->kind is determined by the resource menu.kind. The default message is @default.

See also
- dialog_item-message
- menu-kind
- dialog_item-label
- class menu
menu ->insert_before: item=menu_item, before=name|menu_item
Insert item before another one. If before is a name, menu<-member is used to translate it into a menu_item. If before is not in the menu, the new item is menu->append’ed to the menu.

See also menu->append and menu->prepend.

menu ->is_off: item=member:menu_item
Find menu-item from object and test whether graphical<->active equals @off.
See also
menu->is_on
menu ->is_on: item=member:menu_item
Find menu-item from object and test whether graphical<->active equals @on.
See also
menu->is_off
menu ->kind: kind={cycle,marked,choice,toggle,popup}
Set how the items are presented and reset menu->multiple_selection to @off. The available options are:
cycle
Only display the selection, in a combo box. Clicking the menu opens a list of all items. Uses little space on the screen.
marked
Show each item with a radio button, or a check box if menu->multiple_selection is @on (see menu<-on_image and menu<-off_image).
toggle
As marked, setting menu->multiple_selection to @on.
choice
A segmented control: a row of joined buttons, of which the selected ones are filled with the accent colour.
popup
Used internally. Popup menus are implemented on top of class menu.
See also
- menu-kind
- class menu
menu ->member: item=member:menu_item
Succeeds if the argument is a member menu_item.

Bugs: Used to set the notion of menu<->current in older versions. In its current definition it is not very useful. Use menu<-member to test membership.

See also
menu<-member
menu ->members: chain
menu->clear the menu and then use menu->append to add each member of the chain to the menu. This implies chain may contain both menu_item objects and plain names.

See also menu_item<-convert and send_list/3.

menu ->modified: modified=bool
Inherits description from: menu<-modified
menu ->next: direction=[{down,up}]
Selects the first item with menu_item<-active after the currently selected menu_item. When the currently selected item is the last or there is no currently selected item, the first active item is selected.

Used internally when menu<-show_selection_only equals @on (menu<->kind: cycle).

menu ->off: item=member:menu_item
Invokes menu_item->active on the indicated menu-item, making the indicated menu-item insensitive.
See also
- menu_item-condition
- menu_item-active
- menu->on
- menu<-member
menu ->on: item=member:menu_item
As menu->off, but activates the menu_item.
See also
menu->off
menu ->prepend: item=menu_item
Associate the argument menu_item as first rather than last item of the menu. See also menu->append and menu->insert_before.
See also
menu->append
menu ->selected: item=member:menu_item, selected=bool
Set menu_item<-selected of item. Equivalent to sending the message directly to the menu_item object, but type-conversion will convert a menu_item<-value to the corresponding menu_item.
menu ->selection: selection=member:menu_item|chain*
Select the specified menu_item or chain of menu_items. All other menu_items are deselected.

If the argument is @nil, this is equivalent to menu->clear_selection,

menu ->status: {inactive,active,preview,execute}
The dialog_item<-status of a menu is not used.
menu ->unlink:
Sets menu_item<-menu of all member items to @nil, clears menu->members and invokes menu->unlink on the super-class.
See also
graphical->unlink
menu ->update: context=[any]
Update the activation of the menu_items in this menu. For each menu_item that has a menu<->condition not equal to @nil, it invokes the menu_item<->condition attribute, providing the following context information:
@receiver The menu_item
@arg1 The argument (i.e. the context)

If the message evaluates successfully, the menu_item is activated, otherwise it is deactivated.

See also
- menu->active_item
- menu->active_all_items
- popup->update

1.96.5 Get methods

menu <-active_item: item=member:menu_item -> active=bool
Returns a boolean, indicating the active status of the referred to menu_item.
See also
menu->active_item
menu <-contains: -> items=chain
Returns the menu<-members chain of menu_item objects.
menu <-item_from_event: event=event -> item=menu_item
When event is an event that occurred on the menu, return the menu_item on which are it occurred. May be used to redefine event-handling of menu's.

Diagnostics: Fails silently when the event did not occur on a menu_item's area.

See also
menu->event
menu <-member: value=any -> member=menu_item
When the argument is a menu_item, return this menu_item if it is part of this menu. Otherwise, find the menu_item that has menu<->value equal to the provided value and return this.

Diagnostics: Fails silently on failure.

Bugs: For backward compatibility, if there is no item with menu_item<-value that matches the specification, it will return the first item for which the conversion of the argument and menu_item<-value to a name yield the same name.

See also
- menu->member
- menu->off
menu <-modified: -> modified=bool
Yields @on if the user has modified the menu since the last menu->selection, menu->modified: @off or menu->default. See also menu->apply.

If menu->modified is set to @on the graphical<-device will be informed using dialog->modified_item. See dialog_item->modified.

menu <-selection: -> values=any|chain*
When menu<-multiple_selection equals @off, returns menu_item<-value of the selected menu_item. Otherwise it returns a new chain with the menu<-value for each of the selected items (the chain may be empty).

Diagnostics: Fails if menu<-multiple_selection equals @off and no items are selected. This should only happen it there are no items in the menu.

See also
menu->selection