Создание свитков

Один из видов интерфейсов, создаваемых в MAXScript – свитки (rollouts) на панели Utility. В свитках содержатся элементы интерфейса: кнопки, текстовые поля, выпадающие списки и т.д. Любой свиток можно и нужно редактировать при помощи средства Visual MAXScript Editor, которое вызывается из падающего меню MAXScript Editor - Tools / Edit Rollout, когда курсор находится внутри тела свитка. С нуля свиток можно создать, вызвав Visual MAXScript Editor из падающего меню 3ds max - MAXScript / Visual MAXScript Editor. Основной свиток, с которого мы начнем, создается при помощи конструкции utility:

utility <var_name><description_string>[rolledUp:<boolean>][silentErrors:<boolean>]
(<utility_body>)
Здесь:
<var_name> – имя глобальной переменной, в которой хранится данный свиток.
<description_string> – название утилиты в списке Utilities свитка MAXScript.
rolledUp: – необязательный параметр, определяющий, будет ли изначально развернут свиток утилиты. Значения: true – свернут, false – развернут (значение по умолчанию).
silentErrors: – необязательный параметр, определяющий, будут ли появляться сообщения об ошибках в окне Listener и в диалоговых окнах во время работы утилиты, в этом случае выполнение утилиты прекращается (все это происходит, если для параметра установлено значение false – оно же по умолчанию). Если установлено значение true, то никаких сообщений об ошибках не выводится, и работа утилиты не прерывается.
<utility_body> – тело утилиты, в котором описывается весь интерфейс, функции и события, происходящие при взаимодействии пользователя с элементами интерфейса (нажатие на кнопку, прокрутка спиннера и т.д.)

Следующий пример создает утилиту, которая перемещает выделенные объекты по прямой от центра выделения до позиции каждого объекта, учитывая оси координат.
utility spread "Spread objects" --ОПРЕДЕЛЯЕМ ИМЯ ПЕРЕМЕННОЙ УТИЛИТЫ (НАЗВАНИЕ УТИЛИТЫ) И ЕЕ ЗАГОЛОВОК
(
local last_amt = 0 --ОПРЕДЕЛЯЕМ И ЗАДАЕМ ЗНАЧЕНИЕ ЛОКАЛЬНОЙ ПЕРЕМЕННОЙ
checkbox x "Spread along x" --СОЗДАЕМ ТРИ ФЛАЖКА
checkbox y "Spread along y"
checkbox z "Spread along z"
spinner spread "Величина:" range:[-1000,1000,0] --СОЗДАЕМ СПИННЕР

on spread changed amt do --КОГДА ИЗМЕНЯЕТСЯ ЗНАЧЕНИЕ В ПОЛЕ СПИННЕРА...
(
delta = amt - last_amt --РАЗНИЦА МЕЖДУ ТЕКУЩИМ И ПРЕДЫДУЩИМ ЗНАЧЕНИЕМ
for obj in selection do --ЗНАЧЕНИЯ ДЛЯ КАЖДОГО ВЫДЕЛЕННОГО ОБЪЕКТА
(
--ВЫЧИСЛЕНИЕ НОВЫХ КООРДИНАТ НА ОСНОВЕ ТЕКУЩЕГО ПОЛОЖЕНИЯ И ЦЕНТРА ВЫДЕЛЕНИЯ
--ФУНКЦИЯ normalize СОЗДАЕТ ВЕКТОР ТОГО ЖЕ НАПРАВЛЕНИЯ НО ЕДИНИЧНОЙ ДЛИНЫ
p = obj.pos + normalize (obj.pos - selection.center) * delta
if x.checked then obj.pos.x = p.x --ЕСЛИ ВКЛЮЧЕН ФЛАЖОК x, ИЗМЕНЯТЬ ПОЛОЖЕНИЕ ПО ОСИ X
if y.checked then obj.pos.y = p.y
if z.checked then obj.pos.z = p.z )
last_amt = amt --СОХРАНИТЬ ЗНАЧЕНИЕ СПИННЕРА КАК ПРЕДЫДУЩУЮ ВЕЛИЧИНУ
) --КОНЕЦ СОБЫТИЯ ИЗМЕНЕНИЯ ВЕЛИЧИНЫ СПИННЕРА
) --КОНЕЦ ОПРЕДЕЛЕНИЯ УТИЛИТЫ

Дополнительные свитки
В утилиту можно вставить дополнительные свитки следующим образом:
utility <utility_name> <description_string>
(
...
rollout <rollout_name> <description_string> [rolledUp:<boolean>] [silentErrors:<boolean>]
(<rollout_body>)
...
on <utility_name> open do --ПРИ ОТКРЫТИИ УТИЛИТЫ...
(
...
--ДОБАВЛЯЕМ СВИТОК, ПОСКОЛЬКУ САМ СОБОЙ ОН НЕ ПОЯВИТСЯ
addRollout <rollout_name> [rolledUp: <boolean>]
...
)
on <utility_name> close do --ПРИ ЗАКРЫТИИ УТИЛИТЫ...
(
...
removeRollout <rollout_name> --УДАЛЯЕМ СВИТОК
...
)
)--КОНЕЦ ТЕЛА УТИЛИТЫ

Параметры конструкции rollout те же самые, что и у utility.

Свойства свитков и утилит
У свитков и утилит есть свойства, вот некоторые из них:
СвойствоОписание
<rollout>.nameимя переменной свитка (строковая величина только для чтения)
<rollout>.titleзаголовок свитка
<rollout>.openсвернут (false) или развернут (true) свиток
<rollout>.controlsмассив со всеми элементами интерфейса (только для чтения)

События свитка и элементов интерфейса в свитке
Вызов события (event) происходит, когда пользователь взаимодействует с элементом интерфейса, для которого данное событие определено:
on <item_name> <event_name> [<argument>] do <expr>
Здесь:
<item_name> – название элемента интерфейса, который вызывает событие.
<event_name> – тип события (зависит от типа элемента)
<argument> – дополнительная переменная, в которую заносится значение элемента.
<expr> - код, который выполняется, когда событие произошло.

Имя событияОписание
pressedнажали на кнопку
changedизменили значение спиннера, в(ы)ключили флажок (радиокнопку)
pickedуказали на объект в сцене
enteredизменили текст в текстовом поле
selectedвыбрали пункт из списка
resizedизменили размер плавающего окна
movedпереместили плавающее окно
openоткрыли свиток или утилиту
closeзакрыли свиток или утилиту