This creates a pop-up menu inside a miniwindow. This is intended to let you click on an item (for example, a piece of inventory), and select "take/drop/equip/wield" and so on.
The window must exist, and be visible, or an empty string is returned.
WindowName: The name of an existing miniwindow
Left: The X position inside the miniwindow
Top: The Y position inside the miniwindow
Items: A string containing the menu items to be displayed, see below.
The X and Y position must be inside the miniwindow (ie. not negative, and not exceeding the miniwindow's defined width and height). Otherwise, an empty string is returned.
You can use WindowInfo (win, 14) and WindowInfo (win, 15) to find where the mouse was last clicked inside this miniwindow.
The Items parameter is a string, containing the menu items to be displayed, separated by the "|" character. Leading and trailing spaces are removed from each item.
For example: Item = "^Sword | - | Wield | Equip | - | Take | Drop "
There must be at least one item, or an empty string is returned.
An item which is empty, or consisting of the character "-" is displayed as a menu separator (horizontal line).
An item which commences with the "^" character is displayed disabled (grayed out, and it cannot be selected). The "^" character is removed.
An item which commences with the "+" character is displayed checked (with a tick mark next to it). The "+" character is removed.
Items may have both a + and ^ in front of them, in either order.
An item which commences with the ">" character represents a nested menu. Subsequent items until a "<" character are in the nested menu.
An item which commences with the "<" character ends a nested menu.
You can display a maximum of 100 selectable items. This does not count nested menus items, disabled items, and separator lines. That is, there can be a maximum of 100 items which can be actually chosen by the player.
The return value is the selected item, if any. If no item is selected (ie. the menu is dismissed) then an empty string will be returned.
In the above example, a menu would be shown like this:
Sword (grayed out)
Thus the return value would be one of:
"" - menu dismissed
"Wield", "Equip", "Take", or "Drop"
Note that the leading and trailing spaces around the items have been removed in the return value.
WARNING - we reserve non alpha-numeric characters in the first position of each item for future expansion. For example, perhaps in future versions "*Equip" might be used to tick the Equip item.
SUGGESTION - we strongly recommend that, if you are creating a menu in response to a mouse-click, you do it on the "mouse up" rather than "mouse down".
The reason for this is that MUSHclient tracks mouse-down events and their corresponding mouse-up events, in order to call the appropriate hotspot routines (mouse-down, mouse-up, mouse-down cancel).
However if you call WindowMenu in response to a mouse-down, the next mouse-up is "swallowed" up by the menu handler, and thus MUSHclient doesn't "see" it. The end result is that MUSHclient thinks the mouse is down, when it is in fact up. This gets the hotspot events out of synchronization, and then subsequent things like mouse-overs are not processed correctly.
So, for best results, draw a menu after a mouse-up. This if in fact what most Windows programs do, if you look carefully. In general, programs don't respond when you click down on the mouse, the action response happens when you let go (the mouse-up event).
Example of nested menus:
Items = "Take | Drop | >Eat | With Fork | With Hands | < | >Emote | Smile | Laugh "
This would display:
(Where Eat and Emote are nested menus)
If the first character of the entire Items string is the "!" character, then the function returns the selected item number rather than the selected string. It still returns an empty string if nothing is selected. The "!" is then removed and the rest of the string treated in the usual way (so you could then start a submenu, for example).
This lets you distinguish between multiple identical items in submenus.
Only items that generate "active" menu elements are counted. That is, divider lines, grayed-out items, and sub-menus are not counted. The first item is item 1.
Items = "!Take |-| ^Drop | >Eat | Fork | Hands | < | >Emote | Smile | Laugh "
In this case we would get:
Divider line: (can't be selected)
Drop: (can't be selected)
Eat -> Fork: 2
Eat -> Hands: 3
Emote -> Smile: 4
Emote -> Laugh: 5
Cancelled: empty string
If the first character of the entire Items string is the "~" character, then the menu alignment is specified by the next two characters. The "~xx" characters are then removed and the rest of the string treated in the usual way (so you could then start a submenu, for example).
The two characters following the "~" are the horizontal and vertical alignments, as follows:
Horizontal: L, C or R (left, centre, right)
Vertical: T, C or B (top, centre, bottom)
Default is top left (so the menu aligns to the specified point and appears on the right and underneath). That is, top left is where the menu starts. The letters are not case-sensitive. Anything other than those letters will be ignored.
Items = "~RBTake | Drop" -- align cursor on right and bottom of point.
If you want to use both "!" and "~" then use "!" first as that is checked for and then removed from the string. Then it checks for "~" next. After that the normal menu processing takes place.
Summary of special characters in the first column:
! : return numeric result (only in first position of entire string)
~ : specify menu alignment (only in first position of entire string, or after "!")
- : separator line
^ : grayed-out item
+ : checked (ticked) item
> : start of nested menu (rest of line is nested menu title)
< : end of nested menu (rest of line is ignored)
Nested menus can be further nested.
Nested menus added in version 4.52. Numeric results added in version 4.65.
Checked items added in version 4.71. Menu alignment added in version 5.05.
Note: Available in version 4.37 onwards.