30.17 Выпадающие меню

Программа на Lisp может вызвать меню, чтобы пользователь мог выбрать альтернативу с помощью мыши. В текстовом терминале, если мышь недоступна, пользователь может выбрать альтернативу с помощью клавиш навигации клавиатуры — C-n, C-p или клавиш со стрелками вверх и вниз.

Функция: x-popup-menu position menu

Эта функция отображает выпадающее меню и возвращает информацию о том, какой выбор сделал пользователь.

Аргумент position указывает, где на экране разместить верхний левый угол меню. Это может быть либо событие нажатия кнопки мыши, либо событие touchscreen-begin (которое указывает, где пользователь нажал кнопку), либо список такого вида:

((xoffset yoffset) window)

где xoffset и yoffset — это координаты, измеренные в пикселях, отсчитываемые от верхнего левого угла window. window может быть окном или фреймом.

Если position равно t, это означает использование текущей позиции мыши (или верхнего левого угла фрейма, если мышь недоступна в текстовом терминале). Если position равно nil, это означает предварительный расчет эквивалентов привязки клавиш для карт клавиш, указанных в menu, без фактического отображения или вызова меню.

Аргумент menu определяет, что отобразить в меню. Это может быть карта клавиш или список карт клавиш (см. Карты клавиш меню). В этом случае возвращаемое значение — это список событий, соответствующих выбору пользователя. Этот список содержит более одного элемента, если выбор был сделан в подменю. (Обратите внимание, что x-popup-menu фактически не выполняет команду, привязанную к этой последовательности событий.) В текстовых терминалах и инструментах, поддерживающих заголовки меню, заголовок берется из строки подсказки menu, если menu — это карта клавиш, или из строки подсказки первой карты клавиш в menu, если это список карт клавиш (см. Определение меню).

Альтернативно, menu может иметь следующий вид:

(title pane1 pane2...)

где каждый pane — это список вида

(title item1 item2...)

Каждый item должен быть ячейкой cons, (line . value), где line — это строка, а value — это значение, которое возвращается, если эта line выбрана. В отличие от карты клавиш меню, nil value не делает элемент меню невыбираемым. Альтернативно, каждый item может быть строкой, а не ячейкой cons; это делает элемент меню невыбираемым.

Если пользователь закрывает меню, не сделав действительного выбора, например, кликнув мышью вне действительного выбора или нажав C-g, то это обычно приводит к завершению работы, и x-popup-menu не возвращает значение. Но если position является событием кнопки мыши (указывающим на то, что пользователь вызвал меню мышью), то завершение работы не происходит, и x-popup-menu возвращает nil.

Примечание по использованию: Не используйте x-popup-menu для отображения меню, если вы можете выполнить эту задачу с помощью префиксной клавиши, определенной с помощью карты клавиш меню. Если вы используете карту клавиш меню для реализации меню, C-h c и C-h a могут увидеть отдельные элементы в этом меню и предоставить по ним справку. Если же вы реализуете меню, определяя команду, которая вызывает x-popup-menu, то средства справки не могут знать, что происходит внутри этой команды, поэтому они не могут предоставить справку по элементам меню.

Механизм панели меню, который позволяет переключаться между подменю перемещением мыши, не может просматривать определение команды, чтобы узнать, что она вызывает x-popup-menu. Поэтому, если вы попытаетесь реализовать подменю с помощью x-popup-menu, это не сможет работать с панелью меню в интегрированном виде. Вот почему все подменю панели меню реализуются с помощью карт клавиш меню внутри родительского меню, а никогда с помощью x-popup-menu. См. Панель меню.

Если вы хотите, чтобы подменю панели меню имело изменяемое содержимое, вам все равно следует использовать карту клавиш меню для его реализации. Чтобы содержимое менялось, добавьте функцию хука в menu-bar-update-hook, чтобы обновлять содержимое карты клавиш меню по мере необходимости.

Переменная: x-pre-popup-menu-hook

Обычий хук, выполняемый непосредственно перед отображением выпадающего меню, либо путем прямого вызова x-popup-menu, либо через карту клавиш меню. Он не будет вызван, если x-popup-menu возвращается по какой-либо другой причине без отображения выпадающего меню.