Использование дерева параметров в скриптах JAWS

Дата публикации:2011
Twitter Facebook Vkontakte

Изменения в пользовательском интерфейсе

Начиная с JAWS версии 9.0, диалог "Настройка информативности JAWS" (Adjust JAWS Verbosity) для активного приложения был заменен на диалог "Настройка параметров JAWS" (Adjust JAWS Options). Новый диалог, как и прежний, можно вызвать при помощи комбинации клавиш Insert+V. Однако в остальном этот диалог претерпел существенные изменения. Вместо обычного списка параметров, теперь в диалоге все параметры представлены в виде многоуровневой древовидной структуры, что облегчает навигацию и поиск нужных параметров.

Дерево параметров может содержать параметры (в документации JAWS может использоваться термин "элемент" (item)) и категории (или узлы(nodes)), которые могут, в свою очередь, содержать вложенные категории и параметры , которые, в свою очередь... Параметры могут иметь различные значения, влияющие на поведение JAWS в активном приложении.

По дереву параметров можно перемещаться при помощи клавиш со стрелками вверх и вниз. Раскрыть категорию, чтобы увидеть содержащиеся в ней вложенные категории и параметры, можно при помощи клавиши со стрелкой вправо. Закрыть категорию можно при помощи клавиши со стрелкой влево.

Кроме дерева параметров, в данном диалоге присутствует окно редактора с текстом подсказки. Этот текст меняется в зависимости от того, на какой категории или параметре расположен курсор в дереве параметров.

Изменения в скриптах

Такие серьезные изменения в пользовательском интерфейсе потребовали изменений и в сценариях JAWS. Хотя комбинация клавиш для вызова диалога настроек не изменилас, но теперь она связана со скриптом AdjustJAWSOptions. Скрипт AdjustJAWSVerbosity также присутствует в файле скриптов по умолчанию (default.jss), но для этого скрипта не назначена комбинация клавиш. При желании, ее можно назначить при помощи Диспетчера клавиатуры.

Рассмотрим необходимый минимум функций для работы с деревом параметров в скриптах JAWS.

Для того чтобы в дереве параметров отобразились параметры, которые мы собираемся использовать в наших сценариях, необходимо выполнить следующие шаги:

Кроме этого, могут потребоваться дополнительные шаги в том случае,если необходимо создавать свои категории и подкатегории.

Замечание: В угоду простоте изложения из нижеследующих примеров исключена обработка ошибок. Также не используется формат сообщений @msg, обязательный для корректной локализации скриптов, а также для скриптов, предназначенных для публичного распространения (иными словами, все строковые литералы помещены непосредственно в код скриптов, а не вынесены в файл сообщений .jsm).

Переопределение скрипта

Чтобы вызвать диалог "Настройка параметров JAWS" (Adjust JAWS Options) для активного приложения, необходимо обратиться к функции OptionsTreeCore.

У этой функции первый аргумент является обязательным, а второй и третий - необязательные. Остановимся пока на первом аргументе, который является строкой, содержащий список добавляемых нами параметров JAWS. Этот список имеет следующий предопределенный формат:

В скриптах вместо символа вертикальной черты можно использовать именованную константу _DLG_SEPARATOR, определенную в файле HjConst.jsh. Это позволит вашим скриптам не зависеть от конкретного значения символа-разделителя.

В общем виде строку списка параметров можно представить так:

"Имя_функции1:Имя_параметра1"+_DLG_SEPARATOR
	+"Имя_функции2:Имя_параметра2" +_DLG_SEPARATOR
	; и так далее для всех добавляемых параметров...
	

Вот пример простейшей реализации скрипта , в котором в дерево настроек добавляются два параметра с именами Параметр1 и Параметр2 (разумеется, в реальных скриптах имена параметров и категорий необходимо выбирать такими, чтобы они характеризовали предназначение параметра или категории):

include "HjConst.jsh"
Script AdjustJAWSOptions ()
var
	string sList
	Let sList = "Option1:Параметр1"+_DLG_SEPARATOR
		+"Option2:Параметр2"
		
	OptionsTreeCore (sList)
EndScript

Теперь, если попробовать вызвать диалог "Настройка параметров JAWS" (Adjust JAWS Options), то в дереве этого диалога в самом начале будет располагаться категория с названием "Параметры имя_конфигурации" (Имя_конфигурации Options), где имя_конфигурации - это имя активной конфигурации (которое, как правило, соответствует имени исполняемого файла активного приложения). Внутри этой категории будут присутствовать два параметра: Параметр1 и Параметр2.

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

Чтобы диалог настроек работал корректно, необходимо для каждого из добавленных параметров определить две функции обратного вызова: функцию, изменяющую значение параметра, и функцию, возвращающую текст для окна подсказки.

Функция, изменяющая значение параметра

Когда в дереве диалога настроек пользователь меняет значение параметра при помощи клавиши Пробел, то JAWS пытается вызвать функцию с именем, которое было указано в строке списка параметров. Также эта функция вызывается, когда необходимо отобразить текстовый вариант текущего значения данного параметра. Для Параметра1 мы указали имя функции Option1. Предположим, что значение этого параметра хранится в глобальной переменной g_bOption1, которая может содержать 0 ("отключено") и 1 ("включено"):

globals
int g_bOption1

Простейший вариант определения функции, изменяющей значение параметра, может выглядеть так:

string Function Option1 (int iState)
; Изменяем текущее значение.
If iState == 0 Then
	let g_bOption1 = not g_bOption1
EndIf

; Возвращаем текстовое описание
; текущего значения.
If g_bOption1  Then
	return "включено"
EndIf
return "отключено"
EndFunction

Как видно из примера, функция принимает один параметр - целочисленное значение iState. Если это значение равно нулю, то функция должна изменить соответствующий параметр (т.е. это, в частном случае, признак того, что пользователь нажал пробел на соответствующем параметре в дереве диалога настроек). Логику изменения параметра определяет сам разработчик скрипта, исходя из предназначения данного параметра. В примере параметр фактически является булевым, что позволяет для его изменения использовать операцию инверсии.

Рассматриваемая функция должна возвращать строковое описание текущего значения. Возвращаемая в этом примере строка будет отображена в дереве параметров напротив Параметра1.

Теперь, если вызвать диалог настройки параметров JAWS, то при помощи пробела можно будет изменять значение Параметра1 с "отключено" на "включено" и наоборот.

Для Параметра2 последовательность действий будет аналогичной, но имя этой функции должно быть Option2, так как именно это имя было указано в строке списка параметров. Также надо предусмотреть глобальную переменную для хранения текущего значения Параметра2.

Функция, возвращающая текст подсказки

Как уже было отмечено, в диалоги "Настройка параметров JAWS" (Adjust JAWS Options), кроме дерева параметров, присутствует окно текстового редактора, в котором отображается текст подсказки для текущей категории или текущего параметра.

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

Имена таких функций состоят из имени функции, указанной в строке списка параметров, и суффикса "Hlp" (без кавычек). Например, для Параметра1 указана функция Option1, тогда функция, возвращающая текст подсказки, будет иметь имя Option1Hlp. Простейший вариант этой функции может выглядеть так:

string Function Option1Hlp (int iState)
	return "Подсказка для Параметра1."
EndFunction

Для Параметра2, соответственно, имя функции примет вид Option2Hlp.

Создание собственных категорий

По умолчанию функция OptionsTreeCore помещает добавляемые параметры в категорию с именем активной конфигурации, которое совпадает с именем исполняемого файла активного приложения. Однако если необходимо явно задавать категории для своих параметров, то это можно сделать, как минимум, тремя способами.

Имена категорий можно указать в списке параметров, который в виде строки передается в качестве первого аргумента функции OptionsTreeCore. В этом случае имя параметра превращается в своеобразный путь, подобно пути в файловой системе, где через разделители указываются вложенные друг в друга каталоги, а завершается все именем файла. В случае с деревом параметров, вместо каталогов, выступают категории, а вместо файла - имя параметра. В качестве разделителя используется символ крышки "^", например:

let sList = "Option1:Категория1^Подкатегория1^Параметр1" + _DLG_SEPARATOR
	+ "Option2:Категория1^Подкатегория2^Параметр2"

Вместо символа "^", можно использовать именованную константу NODE_PATH_DELIMITER, определенную в файле UO.jsm.

Однако такой способ указания вложенных категорий не очень удобен.

Второй способ заключается в том, что название категории, в которую будут помещены параметры, можно непосредственно передать третьем аргументом функции OptionsTreeCore. При этом второй аргумент этой функции должен быть False или 0. Однако следует учесть, что в указанную категорию будут помещены только те параметры, для которых не указаны категории в строке списка параметров. Например:

Let sList = "Option1:Параметр1"+_DLG_SEPARATOR
	+"Option2:Параметр2"+_DLG_SEPARATOR
	+"Option3:Категория5^Параметр3"
	
	OptionsTreeCore (sList,0,"Категория1")

В результате выполнения этого фрагмента в дереве параметров будут созданы две категории: Категория1 и Категория5. В Категорию1 будут помещены Параметр1 и Параметр2, а в Категории5 окажется Параметр3.

Третий способ предполагает знакомство со специальной функцией ConvertListToNodeList, которая переформатирует определенный список параметров, добавляя ко всем элементам указанную категорию.

При вызове Функции ConvertListToNodeList передаются два аргумента. Первый аргумент - это ссылка на строку списка элементов. Этот список будет преобразован в список с указанием категории.

Второй аргумент - это имя категории (включая подкатегории, разделенные символом "^"), которое будет добавлено к первому параметру, то есть к списку. За подробностями можно обратиться к справке Диспетчера скриптов или FSDN (раздел Strings).

Вот пример использования этой функции:

Let sList = "Option1:Параметр1"+_DLG_SEPARATOR
	+"Option2:Параметр2"
	
ConvertListToNodeList(sList, "Подкатегория1")
ConvertListToNodeList(sList, "Категория1")
OptionsTreeCore (sList)

Этот пример показывает, что при помощи функции ConvertListToNodeList можно создавать иерархию вложенных категорий (причем начинать надо с самой нижней). В результате получим в дереве параметров Категорию1, в которую будет вложена Подкатегория1, в которой будут располагаться Параметр1 и Параметр2. Тот же результат можно получить однократным вызовом функции ConvertListToNodeList , указав вторым аргументом строку с категорией и подкатегорией:

ConvertListToNodeList(sList, "Категория1^Подкатегория1")

Другие примеры использования можно посмотреть в функциях TreeCoreGet*Options в файле UserOptions.jss.

Подсказка для категории

Чтобы передать текст подсказки для созданной категории, надо определить собственный вариант функции NodeHlp . Вариант этой функции по умолчанию определен в файле UserOptions.jss.

Вот пример пользовательского определения в файле скриптов для конкретного приложения (подразумевается, что создана категория по умолчанию, имя которой содержит имя активной конфигурации):

string Function NodeHlp (string sNodeName)
	If StringContains (sNodeName, GetActiveConfiguration()) Then
		return "Текст подсказки для нашей категории!"
	EndIf
	Return NodeHlp (sNodeName)
EndFunction

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

Если бы была создана не категория по умолчанию, а категория с конкретным именем (например, "Категория1"), то проверку надо было бы выполнять на совпадение имен категорий:

If 0 == StringCompare(sNodeName, "Категория1") Then
; ...


Распространение материалов сайта означает, что распространитель принимает условия лицензионного соглашения.
Идея и реализация: © Владимир Довыденков и Анатолий Камынин,  2004-2017
Rambler's Top100