- •«Здравствуй, мир!»
- •Особенности типов окна dialog и palette
- •Пример: живая прокрутка
- •Использование пиктограмм индизайна
- •Определение, какой из элементов списка выбран
- •Упорядочение списков
- •Перемещение объектов списка
- •Добавление иллюстраций в список
- •Списки в несколько колонок
- •Опережающий выбор из списка во время набора
- •Списки как индикаторы процесса
- •Флэшплейер
- •Размер и положение
- •Изменение размера окна
Написание скриптов. Пользовательский интерфейс
Перевод статьи http://www.kahrel.plus.com/indesign/scriptui.html (v.1.2)
В тексте комментарии заключены в фигурные и наклонные скобки {/…/} и окрашены синим цветом.
Введение
ScriptUI — это модуль семейства программ Adobe CS, начиная с версии CS3, с помощью которого можно добавлять в скрипты диалоги. Модуль входит в состав ExtendedScript Toolkit (ESTK), и сделанные в нём диалоги можно использовать в скриптах для всех приложений Creative Suite, далее CS.
Хотя, этот документ посвящен организации диалогов в скриптах, выполняемых в программе InDesign, теоретически всё сказанное здесь, применимо и к скриптам для других программ CS.
Руководство посвящено только ScriptUI, предполагается, что читатель имеет достаточно знаний о JavaScript.
Руководство полностью описывает среду создания диалогов, и его надо рассматривать как дополнение к основному документу по скриптописанию — JavaScript Tools Guide.
«Здравствуй, мир!»
Самый простейший скрипт выводит сообщение на экран. Вот создание окна на экране и помещение в него текста:
var myWindow = new Window ("dialog")
var myMessage = myWindow.add ("statictext");
myMessage.text = "Здравствуй, мир! Hello, world! [ ОКНО dialog ]";
myWindow.show ( );
Вот что будет при его запуске:
Первая строка определяет новое окно типа dialog; вторая определяет управление этим окном, в данном случае это statictext; третья определяет содержимое окна; последняя выводит окно на экран. Чтобы закрыть окно, надо щелкнуть мышкой на красной кнопке с крестиком.
Чтобы закрыть окно, надо щелкнуть мышкой на красной кнопке с крестиком. Позднее будут рассмотрены более изящные способы закрытия диалогов.
Особенности типов окна dialog и palette
Есть два типа окна: dialog и palette. Вы уже знаете, в чем межу ними разница, т.к. название диалог и палитра отражает, как работают в InDesign подобные окна. Окно dialog остается активным, пока вы с ним работаете, и пока оно открыто, вы ничего другого делать не можете. Пример — диалоги TextFrame Options или Paragraph Rules. Вы сможете продолжить работу в программе только после закрытия этих окон. {/Диалоговые окна такого типа принято называть модальными. Окно типа palette отображается на экране, но не препятствует работе в программе InDesign. Пример такого окна — палитры Paragraphs или Characters. Такие диалоговые окна называются немодальными. Для работы такого окна в скрипте должна быть инструкция #targetengine "session"/}
Визуально окна этих типов можно различить по признаку, что диалоги имеют кнопку ОК и Cancel, а палитры не имеют. Хотя можно сделать и палитру с такими кнопками, и диалог без них (хотя вряд ли он будет где-то полезен).
{/Для полноты картины надо сказать, что в объектной модели есть и третий тип окна — window, но он ведет себя точно также как palette./}
Окно типа dialog
Приведенный выше скрипт создает окно типа dialog.
Окно типа palette
Чтобы сделать окно типа palette, надо определить этот тип при объявлении окна, и определить используемый движок (engine) — строка #targetengine "session" в следующем скрипте.
#targetengine "session";
var myWindow = new Window ("palette")
var myMessage = myWindow.add ("statictext");
myMessage.text = "Здравствуй, мир! Hello, world! [ ОКНО palette ]";
myWindow.show ( );
Попробуйте оба скрипта, чтобы убедиться, что первый блокирует работу, пока не закроешь окно, а второй позволяет работать при открытом окне.
Налицо и некоторые несущественные различия в оформлении окон в части скругления углов и разного размера кнопок.
Интересно, хотя не имеет никакой практической важности факт, что в программе InDesign диалоговые окна имеют скругленные углы, но кнопка закрытия окна отсутствует (установки Textframe, Paragraph Style и т.п.), а вот окна палитр всегда с прямыми углами и имеют кнопку закрытия (окно Find/Change, преобразование URL в гиперссылки и пр.).
Добавление инструментов управления
В первом скрипте была управляющая строка statictext. Этот тип управления позволяет добавить в окно какой-нибудь текст. Для помещения текста использовалась вторая строка
myMessage.text = "Здравствуй, мир!";
но можно обойтись и одной строкой:
var myMessage = myWindow.add ("statictext", undefined, "Здравствуй, мир!")
т.е. написать текст как параметр метода add().
В этой строке оператор undefined используется как заместитель параметров, которые не будут рассмотрены в этом руководстве, а именно размер и положение текста в окне или другом контейнере (позднее мы вернемся к контейнерам внутри окна).
Первый рабочий пример
Перед тем как углубиться в детали всех других средств управления, сделаем простой скрипт, показывающий основные особенности окна ScriptUI. Обсуждая этот пример вы увидите, как обычно подходят к созданию окон, это похоже на процесс конструирования — сперва определяются основные моменты, затем выбираются те, что более управляемы, чтобы улучшить вид окна. Будет сделан скрипт, запрашивающий у пользователя данные.
Ввод текст выполняется при помощи оператора управления edittext. Чтобы указать, что это поле для ввода данных, надо при помощи оператора statictext добавить отдельно приглашение.
var myWindow = new Window ("dialog", "Форма");
myWindow.add ("statictext", undefined, "Имя:");
var myText = myWindow.add ("edittext");
myWindow.show ();
Обратите внимание, что окно теперь с заголовком «Форма». Заметьте также, что поле ввода стоит ниже приглашения («Имя:»), что не есть хорошо. Предположительно, что ориентация окна по умолчанию имеет тип column. Чтобы изменить этот тип, нужен соответствующий оператор в скрипте (вторая строка):
var myWindow = new Window ("dialog", "Форма");
myWindow.orientation = "row";
myWindow.add ("statictext", undefined, "Имя:");
var myText = myWindow.add ("edittext");
myWindow.show ();
Результат несколько лучше, но поле ввода очень маленькое. Кроме того, надо сделать так, чтобы по умолчанию были введены какие-то данные.
var myWindow = new Window ("dialog", "Форма");
myWindow.orientation = "row";
myWindow.add ("statictext", undefined, "Имя:");
var myText = myWindow.add ("edittext", undefined, "Петр");
myText.characters = 30;
myWindow.show ();
Теперь можно для управляющего оператора edittext определить длину строки вводимых данных, это делается указанием значения свойства characters этого оператора.
Далее будут показаны другие способы управления длиной строки.
В этом диалоге, чтобы изменить имя, пользователь должен поместить курсор в текстовое поле. Если скрипт поместит курсор в это поле и выделит текст, то такое решение будет намного полезнее предыдущего. Это выполняется строкой myText.active = true
var myWindow = new Window ("dialog", "Форма");
myWindow.orientation = "row";
myWindow.add ("statictext", undefined, "Имя:");
var myText = myWindow.add ("edittext", undefined, "Петр");
myText.characters = 30;
myText.active = true;
myWindow.show ();
Теперь добавим кнопки, в нашем случае OK и Cancel. Это делается при помощи управляющего оператора button:
var myWindow = new Window ("dialog", "Форма");
myWindow.orientation = "row";
myWindow.add ("statictext", undefined, "Имя:");
var myText = myWindow.add ("edittext", undefined, "Петр");
myText.characters = 30;
myText.active = true;
myWindow.add ("button", undefined, "OK");
myWindow.add ("button", undefined, "Cancel");
myWindow.show ();
Поскольку тип ориентации окна выбран row, то у нас и приглашение, и текстовая строка, и кнопки вытянуты в одну линию. Но это не лучший вариант.
Можно вернуться к стандартному значению column, но сгруппировать поля приглашения и поле ввода текста в одну группу (myInputGroup), а кнопки в другую кнопку(myButtonGroup):
var myWindow = new Window ("dialog", "Форма");
var myInputGroup = myWindow.add ("group");
myInputGroup.add ("statictext", undefined, "Имя:");
var myText = myInputGroup.add ("edittext", undefined, "Петр");
myText.characters = 30;
myText.active = true;
var myButtonGroup = myWindow.add ("group");
myButtonGroup.alignment = "right";
myButtonGroup.add ("button", undefined, "OK");
myButtonGroup.add ("button", undefined, "Cancel");
myWindow.show ();
Были созданы две группы myInputGroup и myButtonGroup, в тексте выше они выделены зеленым цветом.
Для объединения полей или кнопок кроме оператора group используется оператор panel. Их отличие в том, что во втором случае вокруг группы появляется рамка. Кроме того, стандартная ориентация объектов group — это row, тогда как для panel это column. Поэтому удалена строка myWindow.orientation = "row"; , ведь стандартная ориентация для panel это column.
Обратите внимание, что объекты в группе командой align (myButtonGroup.alignment = "right") выровнены вправо. Позже будут еще примеры применения этой команды.
Ниже группа кнопок будет заключена в рамку:
var myWindow = new Window ("dialog", "Форма");
var myInputGroup = myWindow.add ("group");
myInputGroup.add ("statictext", undefined, "Имя:");
var myText = myInputGroup.add ("edittext", undefined, "Петр");
myText.characters = 26;
myText.active = true;
var myButtonGroup = myWindow.add ("panel");
myButtonGroup.orientation ("row");
myButtonGroup.add ("button", undefined, "OK");
myButtonGroup.add ("button", undefined, "Cancel");
myWindow.show ();
{/Понятие о контейнерах
Новое окно, созданное командой new Window(), по своей сути является контейнером, в который помещаются элементы управления – кнопки, текст, поля ввода, списки, радиокнопки, чекбоксы и т.д. Но существуют и другие типы контейнеров в ScriptUI и один из таких типов мы сейчас рассмотрели – это группа элементов. Следующий тип контейнеров – panel, также служит для организации элементов в окне. И третий тип контейнеров — панель с вкладками, называемая TabbedPanel. Вы можете как угодно вкладывать один контейнер в любой другой, например в главное окно добавить три панели, затем в первую панель добавить элемент Static Text еще панель, во вторую панель можете добавить группу и панель с вкладками, и на каждой вкладке снова разместить панели с элементами, а в третьей – разместить прогрессбар и т.д. Все элементы и контейнеры добавляются при помощи метода add().
Элементы, добавленные в какой-нибудь контейнер, считаются дочерними по отношению к нему. И если вы решили скрыть какой-то контейнер, то исчезнут и элементы, расположенные на нем. /}
Добавим в окно контейнер типа panel, чтобы заключить в общую рамку все поля:
var myWindow = new Window ("dialog", "Форма");
var myPnl = myWindow.add ("panel");
var myInputGroup = myPnl.add ("group");
myInputGroup.add ("statictext", undefined, "Имя:");
var myText = myInputGroup.add ("edittext", undefined, "Петр");
myText.characters = 20;
myText.active = true;
var myButtonGroup = myPnl.add ("group");
myButtonGroup.add ("button", undefined, "OK");
myButtonGroup.add ("button", undefined, "Cancel");
myWindow.show ();
Обратите внимание, что в группах теперь не определен явно тип ориентации. В данном случае он не нужен: ведь в окне всего два объекта, и стандартная ориентация для панели — колонка, а для группы — строка.
{/Но явным указанием ориентации в панели и группе можно получить такие результаты:
|
|
/}
Панели — это хорошие инструменты скриптинга в создании окон. При правильном использовании создаваемые окна легко настраиваются. Например, если надо, чтобы кнопки были справа одна над другой, то всё, что надо сделать — это поместить в скрипт два оператора ориентации, в следующем примере они отмечены зеленым цветом.
var myWindow = new Window ("dialog", "Форма");
myWindow.orientation = "row";
var myInputGroup = myWindow.add ("group");
myInputGroup.add ("statictext", undefined, "Имя:");
var myText = myInputGroup.add ("edittext", undefined, "Петр");
myText.characters = 20;
myText.active = true;
var myButtonGroup = myWindow.add ("group");
myButtonGroup.orientation = "column";
myButtonGroup.add ("button", undefined, "OK");
myButtonGroup.add ("button", undefined, "Cancel");
myWindow.show ();
Для выравнивания групп по вертикали надо добавить строку myWindow.alignChildren = "top" (выделена зеленым). {/Свойство alignChildren используется для выравнивания дочерних элементов./}
var myWindow = new Window ("dialog", "Форма");
myWindow.alignChildren = "top";
myWindow.orientation = "row";
var myInputGroup = myWindow.add ("group");
myInputGroup.add ("statictext", undefined, "Имя:");
var myText = myInputGroup.add ("edittext", undefined, "Петр");
myText.characters = 20;
myText.active = true;
var myButtonGroup = myWindow.add ("group");
myButtonGroup.orientation = "column";
myButtonGroup.add ("button", undefined, "OK");
myButtonGroup.add ("button", undefined, "Cancel");
myWindow.show ();
Предположим, что окно нас устраивает, и вернемся к вопросу, как в скрипте сохранить введенный пользователем текст. В нашем примере есть два события — пользователь щелкает на кнопке ОК (это эквивалентно нажатию на клавишу Enter) или щелкает на кнопке Cancel (это эквивалентно нажатию на клавишу Esc).
Скрипт работает так: если нажата кнопка ОК, строка myWindow.show () возвращает 1, в другом случае будет возвращена 2.
Эту проверка в скрипте реализуется так:
if (myWindow.show () == 1)
var myName = myText.text;
else
exit ();
т.е. веденный текст берется из myText.text.
И полностью скрипт может выглядеть так:
var myName = myInput ();
// rest of the script
function myInput ()
{
var myWindow = new Window ("dialog", "Форма");
var myInputGroup = myWindow.add ("group");
myInputGroup.add ("statictext", undefined, "Имя:");
var myText = myInputGroup.add ("edittext", undefined, "Петр");
myText.characters = 20;
myText.active = true;
var myButtonGroup = myWindow.add ("group");
myButtonGroup.add ("button", undefined, "OK");
myButtonGroup.add ("button", undefined, "Cancel");
if (myWindow.show () == 1)
return myText.text;
else
exit ();
}
Форматирование фрейма окна
Существуют некоторые особенности, определяющие вид палитр и диалогов.
Можно решить убрать кнопку закрытия окна:
myWindow = new Window ("dialog", "Example", undefined, {closeButton: false})
myWindow.add ("statictext", undefined, "closebutton: false");
myWindow.show ();
Можно сделать фрейм без бордюра:
myWindow = new Window ("dialog", "Example", undefined, {borderless: true})
myWindow.add ("statictext", undefined, "borderless: t rue");
myWindow.show ();
Такие безбордюрные фреймы минималистичны, по сути это просто серые панели. Их вид можно улучшить, нарисовав вокруг них контур (добавив панель):
myWindow = new Window ("dialog", undefined, undefined, {borderless: true});
myWindow.margins = [0,0,0,0];
myPanel = myWindow.add ("panel");
myPanel.add ("statictext", undefined, "borderless but framed. Окно без бордюра, но оконтурено");
myWindow.show ();
Заметьте, что фрейм — это бордюр не окна, а панели.
На этом основы построения окон завершены, вернемся к деталям организации содержимого окон.
Элементы управления
Элемент управления statictext
Упомянут для полноты освещения. О нем нечего сказать к тому, что было сказано раньше.
Элемент управления edittext
Был рассмотрен ранее. Он используется для получения данных от пользователя. По умолчанию вводится одна строка, и есть полезное свойство multiline, позволяющее вводить несколько строк.
var myWindow = new Window ("dialog", "Multiline");
var myText = myWindow.add ("edittext", [0, 0, 150, 70], "", {multiline: true});
myText.active = true;
myWindow.show ();
Второй параметр элемента управления edittext — размер окна [Xлв Yлв Ширина Высота] (обратите внимание, что формат описания окна отличен от того, что принят в программе InDesign.)
При вводе чисел (перевод строки Crtl+Enter) при переполнении окна становится активной полоса прокрутки.
{/У этого элемента есть еще одно интересное свойство: noecho, по умолчанию установленное в False. Если его установить в true:
var paswrd = myInput ();
function myInput ()
{
var myWindow = new Window ("dialog", " Введите пароль:",undefined,{closeButton: false});
var myText = myWindow.add ("edittext", [0, 0, 170, 20], "", {noecho: true});
var myButtonGroup = myWindow.add ("group");
myButtonGroup.add ("button", undefined, "OK");
myButtonGroup.add ("button", undefined, "Cancel");
if (myWindow.show () == 1)
return myText.text;
else
exit ();
}
то вводимый текст в поле ввода не будет отображаться. Это можно использовать для создания скрипта, запрашивающего пароль./}
Хотя этот инструмент для ввода данных называется так многообещающе — редактируемый текст (edittext) — возможности инструмента в скриптах для InDesign ограничены. Не предусмотрено средств для ввода чисел, единиц измерения и пр. Если надо указывать единицы измерения, это надо делать самим. Пример работы ввода размеров можно найти в скрипте помещения сносок на внешнем поле страницы http://www.kahrel.plus.com/indesign/sidenotes.html
http://adobeindesign.ru/2009/06/06/dinamicheskie-sidenotes-cs4/
В Windows есть проблема отображения текста в окне, заключающаяся в том, что если предусмотрен выбор текста (.active = true), этот текст иногда отображается некорректно:
var w = new Window ("dialog");
var e = w.add ("edittext", undefined, "abcdefghijklmnopqrstuvwxyz");
e.active = true;
w.show();
Видно, что размер поля для текста скрипт создал верно, но текст в этом поле размещен неправильно.
Для исправления ситуации надо в скрипт добавить строку (выделена зеленым):
w = new Window ("dialog");
e = w.add ("edittext", undefined, "abcdefghijklmnopqrstuvwxyz");
w.layout.layout();
e.active = true;
w.show();
Позже функция layout() будет рассмотрена более детально.
