Индикатор исполнения задачи, он же прогрессбар, он же градусник…
А мужики-то не знают!..
В обсуждавшейся недавно теме пост 20 вывел на такую ссылку: пост 527 и 528. Этот пример организации прогрессбара стал мне знаком после перевода на русский язык руководства Питера Карела по интерефейсу скриптов:
Элемент интерфейса progressbar (индикатор выполнения задания)
Этот элемент управления используется для вывода на экран одной или нескольких линий, отображающих ход исполнения задания. В основе простая идея — длительность линии и время исполнения скрипта связаны между собой. Пока не было лучшего примера использования этого инструмента, кроме скрипта Марка Аутрета (Marc Autret). Вот код этого скрипта: (далее идет код, на который ссылается упомянутый ранее пост 527).
Для меня слова Карела «Пока не было лучшего примера использования этого инструмента, кроме скрипта Марка Аутрета» стали аргументом сделать этот скрипт своим инструментом, и он уже успешно используется в нескольких последних программах. Приглашаю всех скриптописцев попробовать его в деле. Карел прав — этот скрипт действительно лучший.
Скрипт отображения прогрессбара. Инструкция по эксплуатации
Что делает каждая из строк
Исходный скрипт был несколько видоизменен, и вот объяснение его организации:
var ProgressBar = function(title) { var w = new Window('palette', title, {x:0, y:0, width:640, height:60},{closeButton: false}), pb = w.add('progressbar', {x:20, y:32, width:600, height:12}), st = w.add('statictext', {x:20, y:12, width:600, height:20}); st.justify = 'left'; w.center(); this.reset = function(msg,maxValue) { st.text = msg; pb.value = 0; pb.maxvalue = maxValue; w.show(); }; this.hit = function() {++pb.value;}; this.hide = function() {w.hide();}; // эта функция гасит окно процесса исполнения задания this.close = function() {w.close();}; } |
this здесь — ключевое слово, указывающее на владельца исполняемой функции, в данном случае ProgressBar.
1 — объявление функции, titul — передаваемый параметр.
3 — окно типа palette шириной 640 и высотой 80 точек, кнопка закрытия окна отключена.
4 — строка, определяющая геометрические размеры и положение прогрессбара внутри окна, определенного строкой выше.
5 — определено место информационной строки. Её положение определено так, что она появится над полосой прогрессбара.
6 — выравнивание строки влево
7 — выравнивание объявленного в строке 3 окна по центру экрана
8 — сброс отображения прогрессбара. Параметры этой функции — сообщение и максимальное значение.
9 — Сообщение из параметров предыдущей строки выводится в поле окна, определенном в 4-й строке.
10 — определено начальное значение прогрессбара.
11 — определено максимальное значение прогрессбара, это второй параметр функции из строки 8
12 — включение отображения окна
14 — функция пошагового наращения текущего значения шкалы
15 — функция скрытия окна
16 — функция закрытия окна
Примечание. Если интересно, в чем состоит изменение исходного кода, так вот описание:
а) добавлено условие {closeButton: false} в строке 3. Сделано по той причине, что коль скоро невозможно щелчком на красном крестике закрыть это окно в процессе исполнения задания, то и пиктограммы быть не должно.
б) в оригинале строка 4 выглядит так: pb = w.add(‘progressbar’, {x:20, y:12, width:300, height:12}, 0, 100), но эти 0, 100 смысла не имеют.
в) в оригинале 11 строка выглядит так: pb.maxvalue = maxValue||0. Т.е. если maxValue определено, его значение присваивается переменной pb.maxvalue. Если не определено, этой переменной присваивается нулевое значение. На мой взгляд, это ненужное усложнение кода. Во-первых, если предполагается воспользоваться этим индикатором, то значение maxValue будет определено. Во-вторых, мало проку иметь для pb.maxvalue нулевое значение.
г) вообще убрана строка pb.visible = !!maxValue; не вижу смысла управлять видимостью шкалы. Если скрипт запускается, прогрессбар должен быть виден всегда.
Как его использовать
Вот несколько строк работающего кода:
var myProgramTitul = " Что для иностранца progressbar, то для русского градусник ";
var pBar = new ProgressBar(myProgramTitul);
pBar.reset(" Задание выполняется... " , 150);
for( i=0 ; i < 150; ++i, pBar.hit()) { // обращение к функци pBar.hit()
…
}
pBar.close(); |
… и комментарий этих строк:
1 — определен заголовок окна с прогрессбаром;
2 — обращение к описанной выше функции ProgressBar
3 — сброс прогрессбара. Вот пример работы упомянутого ранее ключевого слова this: определив в строке прогресс бар с именем pBar, определив в скрипте this.reset = function(msg,maxValue), тут пишем pBar.reset(» Задание выполняется… » , 150), и в окне этого прогрессбара будет выведено сообщение » Задание выполняется… «, и максимальное значение прогрессбара установлено равным 150.
4 — в цикле for, в поле изменения счетчика цикла ++i через запятую указано обращение к функции pBar.hit(), которая при каждом вызове её наращивает длину полосы на один шаг.
Вот, собственно, и всё! Весь интерфейс скрипта как на ладони!
Этот пример в файле gradusnik.jsx, дорабатывайте его под свои задачи — добавьте строки в свой скрипт, сделайте свой заголовок окна прогрессбара (в моем примере это переменная myProgramTitul) и свое сообщение, выводимое в окне (текстовая переменная в третьей строке), и получите замечательный градусник!
Ну а когда всё так просто, почему бы не покуролесить, не попробовать найти другие варианты использования этого инструмента? : ))
А можно двигать полоску не вперед, а назад?
В скрипте gradusnik1.jsx, полоска сперва нарастает, двигаясь слева направо, а затем уменьшается справа налево. Сделано это с помощью введения новой функции сброса this.reset_dn, устанавливающей начальное значение прогрессбара в максимальное значение, и в цикле for при наращении переменной вызывается функция this.decr(), пошагово уменьшающая длину прогрессбара: this.decr = function() {—pb.value;}
А можно в одном окне отображать несколько процессов?
Хороший вопрос, на который есть утвердительный ответ.
Действительно, мы определили текстовое поле st для вывода названия процесса, и переменную pb для графического отображения состояния этого процесса. А кто мешает сделать несколько таких пар параметров в одном окне? Например, первая пара отображала бы общее число заданий, а вторая — состояние исполнения текущего задания.
Такая задача решена в скрипте gradusnik2.jsx.
Если изменить значение переменной SecDirectionR2L на true, то в процессе демонстрации полоса второго уровня будет ползти справа налево.
Михаил Иванюшин
Скачать скрипты прогрессбара
P.S.
Обязательна ли инструкция #targetengine?
Справочное руководство по скрипам, описывая демонстрационный пример прогрессбара, предписывает включать эту инструкцию. Но на самом деле и без неё всё работает. Использование этого оператора имеет смысл, если несколько скриптов используют один и тот же прогрессбар.
Правильно ли я понял. Весь код, ход которого, надо проиллюстрировать, пишется в тело function main()?
Ну написал я простенький код вывода посткрипта (командой myPrintPrefs.activePrinterPreset = app.printerPresets.item(«my_ps»);
и после строки
for( i=0 ; i < myValue; ++i, pBar.hit()) { $.sleep(myTime); }
вставил свою
mDoc.print(false);
Но скорость закрашивания прогресс-бара никак не коррелирует с процессом печати. Оно закрашивается почти до конца, а потом ждет выполнения фоновой задачи и только потом закрывается. То есть пока играет роль как бы баннера, оповещающего, что задача еще не выполнена. Можно ли как-то увязать темп закраски бара с самой задачей?
Dimmo, ошибка в том, что процедура mDoc.print(false); оказалась вне фигурных скобок цикла for.
Поэтому он сперва отрабатывает $.sleep и показывает этот процесс, а потом выполняет mDoc.print(false).