• Содержание
  • Разработка приложений с помощью Mozilla / автор: Н.Макфарлейн
    8. Глава: Навигация

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

    У конечного пользователя, опытного и нетерпеливого или запутавшегося и растерянного, должна быть свобода в перемещении по приложению. Такое перемещение называется навигацией. Первое правило навигации: не отпугивайте пользователя. В навигационной стратегии всегда должны быть знакомые подсказки и знакомая реакция на действия пользователя, никогда не следует удивлять пользователя или бросать ему вызов. XUL предоставляет теги для навигации, соответствующие элементам управления почти всех приложений с графическим интерфейсом. Сюда входят полосы прокрутки, панели инструментов и меню. Как и для всех XUL-тегов соглашения о присвоении им имен ясны:

    <scrollbar orient="horizontal"/>
    

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

    XUL-приложения более структурированы, чем HTML-приложения. Традиционно в Internet пользователь может свободно просматривать любую предоставленную информацию. Техники графического дизайна могут влиять на это поведение, но пользователь всегда как будто разглядывает "витрины". В XUL-приложениях такой неструктурированной навигации гораздо меньше. Пользователи склонны выполнять одни и те же задачи снова и снова (если приложение используется активно), и иногда приложение накладывает достаточно сильные ограничения на то, что пользователь может делать. Этот более деловой и структурированный стиль взаимодействия означает расчет на то, что приложение будет работать плавно. Поэтому навигации в XUL требуется уделить некоторое внимание при проектировании, если приложение должно работать безупречно.

    На иллюстрации в начале этой главы выделены те части Mozilla, которые участвуют в создании навигационной системы. Видно, что эта система строится на основе уже хорошо знакомых нам частей платформы. По большей части навигация - это XUL-теги, а это значит больше отображения на экране, больше элементов управления, основанных на системных элементах, и больше фреймов. Как и для простых тегов форм, XBL-связки, лежащие в основе тегов, жизненно важны при написании скриптов.

    В главе 6, "События", говорилось, что кольцо фокуса в Mozilla связывает элементы формы так, что можно получать к ним доступ с клавиатуры. Кольцо фокуса и другие дополнительные технологии будут исследоваться далее в этой главе.

    8.1. Системы навигации

    Платформа Mozilla содержит несколько частей, связывающих вместе существующие XUL-элементы навигации. Каждая из этих частей предоставляет основу для коммуникации между пользователем и платформой. Каждая часть - некая высокоуровневая модель, реализованная поверх инфраструктуры, описанной в главе 6, "События".

    8.1.1. Визуальная навигация и навигация по памяти

    Воспринимая окружающее, мы используем и зрение, и память. Мы хорошо управляемся с обработкой обоих типов информации. Неудивительно, что программные системы тоже используют и зрение, и память для помощи пользователям в навигации, но иногда что-то одно помогает значительно лучше.

    Визуальная навигация зависит от искусства графического дизайнера. Хорошо продуманное и спроектированное отображение упрощает поиск того, что нужно пользователю. Классический пример - визуально ориентированное приложение, вроде Adobe Photoshop. Хотя в нем и есть система меню, она вторична по отношению к навигации по палитрам и холсту с помощью указателя мыши. Пользователь Photoshop знает, что если щелкнуть по текущему выделению правой кнопкой мыши с выбранным инструментом Flood Fill, т.е. заливка (который находится здесь), выделенная часть окрасится в текущий фоновый цвет.

    Визуальная навигация особенно важна, когда пользователь сталкивается с чем-либо в первый раз.

    Навигация по памяти применяется, когда пользователь для завершения задачи задействует привычки или память. Хорошо продуманная последовательность вызываемых с клавиатуры команд помогает пользователю запомнить, как делать те или иные вещи. Очевидный пример такой навигации - командная строка. Если пользователь хорошо помнит команды, командная строка становится очень выразительным и эффективным способом решения задач. В оконных приложениях также возможна навигация по памяти. В Microsoft Windows почти во всех приложениях нажатие последовательности Alt-F-S (File | Save, Файл | Сохранить) приводит к сохранению текущего документа. Использование последовательностей клавиш обеспечивает быструю навигацию - возможно, самую быструю.

    Навигация по памяти очень важна, если пользователь выполняет повторяющиеся действия.

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

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

    В XUL Mozilla отходит обратно к навигации по памяти, эффективной для опытных пользователей. XUL предоставляет обширную поддержку клавиатурной навигации. Любой необходимый нетривиальный графический дизайн становится заботой разработчика приложения. В традиционных приложениях XUL по-прежнему предоставляет поддержку визуальной навигации в виде строк меню и прокрутки.

    Таким образом, технологии Mozilla упрощают создание систем с навигацией по памяти. Сложное визуальное размещение остается на долю разработчика приложения и не обеспечивается поддержкой, кроме простейшего CSS 2 (которая, тем не менее, полная) и XUL.

    8.1.2. Кольцо фокуса

    Кольцо фокуса в Mozilla - система для простых перемещений по документу. В XUL и HTML эти перемещения должны быть между элементами, которые пользователь может изменить, например, между полями формы.

    Если пользователю нужно что-то ввести в форму, целесообразно работать в каждый момент времени только с одним элементом формы. Как и HTML, XUL выводит на первый план такие элементы по одному. Про элемент, на данный момент доступный для пользовательского ввода, говорят, что у него есть фокус.

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

    Все элементы управления из кольца фокуса Mozilla достижимы. Простейший путь понаблюдать за этим порядком переходов - пройтись по кольцу с помощью клавиши Tab. Попробуйте сделать так в любом окне Mozilla, где открыт XUL- или HTML-документ. Кроме клавиши Tab любой элемент кольца может получить фокус по нажатию левой кнопки мыши. В каждом окне Mozilla есть только одно кольцо фокуса.

    Некоторые элементы управления, похожие на элементы формы, не входят в кольцо фокуса. Например, <toolbarbutton> и <menu>. Это так потому, что основная цель кольца фокуса - помощь пользователю при вводе данных. Элементы управления, которые больше относятся к управлению приложением, например, меню, не входят в это кольцо.

    Кольцо фокуса в Mozilla довольно сложное. Оно может перейти к XBL-связке и сделать активной определенную часть ее содержимого. Это дает пользователю возможность взаимодействовать с небольшими частями данной связки. Таким образом в связку, которая обычно составляет из разных частей единый целый элемент управления, может проникнуть фокус. Фокус также может проникать во встроенное содержимое. XUL-документ может содержать теги <iframe>, отображающие другие документы внутри основного. Кольцо фокуса попадает в эти документы и оттуда включает все подходящие элементы. Также в кольцо добавляются и сами документы целиком. Чтобы в этом убедиться, следует загрузить HTML-документ, содержащий форму, в любой браузер Mozilla. При нажатии Tab вы будете перемещаться по кольцу фокуса: и по отдельным элементам формы и по всему HTML-документу, и по XUL-частям окна браузера, когда до них дойдет фокус.

    Так как кольцо фокуса включает в себя целые встроенные документы, в нем есть и иерархичность. Чтобы понять это, представьте, что домашняя страница Google (www.google.com) отображается в браузере и что курсор находится в поле ввода поискового слова этой страницы. Все эти элементы находятся в фокусе: и поле ввода, и HTML-документ, являющийся страницей Google, и окно, отображающее XUL-документ - приложение браузера. В терминах XML элементами, получившими фокус, будут: HTML-тег <INPUT TYPE="text">, XUL-тег <iframe>, HTML-тег <HTML> и самый внешний XUL-тег <window>.

    Эта иерархичность кольца фокуса нужна для удобства пользователя, но также применяется и в системе команд Mozilla, описанной в главе 9, "Команды". Там метод commandDispatcher.getControllerForCommand() в поисках подходящего контроллера просматривает кольцо фокуса иерархически.

    У большинства XUL-тегов, которые могут получать фокус, есть методы focus() и/или blur(), которые могут использоваться в скриптах. До недавнего времени в реализации кольца фокуса встречались небольшие ошибки, которые иногда влияли на состояние XUL-окон. С версии 1.4 кольцо фокуса стало вполне надежным.

    8.1.2.1. Гиперссылки

    Когда Mozilla отображает HTML-страницы, все гиперссылки в ней включаются в кольцо фокуса. В XUL нет гиперссылок. Если XUL и HTML делят между собой один документ (с помощью атрибута xmlns), XUL-теги и HTML-гиперссылки могут сосуществовать в одном кольце фокуса.

    8.1.3. Система меню

    Отдельная от кольца фокуса система навигации - система меню Mozilla. Переход в нее осуществляется по нажатию клавиши Alt (или Control или Meta в более ранних UNIX-системах), по наведению указателя мыши на элемент строки меню или по нажатию на этот элемент.

    Система навигации через меню - не просто последовательность тегов <key>. Это фундаментальная часть поддержки XUL платформой. Чтобы можно было использовать систему меню, в отображаемом XUL-документе должен содержаться тег <menubar> (строка меню). Перемещаться по меню можно только из такой строки меню.

    Доступ к отдельным элементам системы меню может быть и прямым, независимым от системы меню. Для этого нужно добавить элементам меню клавиши доступа. Этот процесс описан в главе 6, "События". Поддержка конкретных тегов описывается ниже.

    8.1.4. Специальные возможности

    Специальные возможности - особенность программного обеспечения, спроектированного с тем расчетом, чтобы сделать его доступным для пользователей с ограниченными физическими возможностями. В Mozilla предусмотрена поддержка специальных возможностей в Microsoft Windows и Macintosh, а у ее UNIX/Linux-версии будет такая поддержка, когда завершится разработка GTK2-библиотек.

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

    На другом полюсе находится сложное решение, предоставляющее программный интерфейс и дающее программистам возможность связывать их ПО и устройства со специальными возможностями с этим решением. Mozilla предоставляет такой программный интерфейс в виде множества XPCOM-интерфейсов, чьи имена начинаются с префикса nsIAccessible. Использование таких интерфейсов - почти (но не совсем) встраивание платформы Mozilla. Эти интерфейсы не рекомендуется применять в случае обычных пользователей.

    Между этими полюсами находится решение, использующее простые техники XML-разметки. Это решение состоит из объявлений стилей @media, XHTML- и XUL-атрибута accesskey и XUL-тега <label>. @media и accesskey подробно описаны в соответствующих стандартах: accesskey в XUL работает точно так же, как и в HTML.

    На уровне реализации эти функции должны использовать специальные возможности системной библиотеки графических элементов. Если это так, то проблема доступности содержимого пользователю - проблема конкретной системной библиотеки, а не приложения. Именно так работает Mozilla. Интерфейсы nsIAccessible предоставляют информацию из XML-документа системной библиотеке.

    Во всех рассуждениях до текущего момента XUL-тег <label> был идентичным тегу <description>, только он мог быть сведен к атрибуту label. Отличия тега <label> от <description> прежде всего видны в области специальных возможностей. Тег <label> предоставляет альтернативное содержимое, необходимое системе специальных возможностей.

    Если у элемента формы есть атрибут label, Mozilla предоставит его содержимое и на экран, и системной библиотеке как вспомогательную информацию о том, что должно быть объявлено пользователю. "Объявить пользователю" означает, что вспомогательная информация будет проговорена компьютером.

    Если у элемента формы нет такого атрибута, Mozilla будет искать тег <label> среди его потомков и использует его. Если и такого тега не найдется, она будет искать тег <label>, чей атрибут id соответствует идентификатору, заявленному в атрибуте control элемента формы. Если и он не найден, значит, дополнительная информация отсутствует.

    В Mozilla поддержка специальных возможностей есть для всех простых XUL-элементов форм. У тегов <menuitem>, <menulist> и <tab> также есть эта поддержка. Специальные возможности для таких тегов реализуются в их XBL-связках.

    8.2. Элементы управления навигацией

    На рисунке 8.1 продемонстрированы все XUL-теги системы навигации на одном снимке.

    XUL-теги для навигации с отладочной разметкой

    Рис. 8.1.  XUL-теги для навигации с отладочной разметкой

    Рисунок 8.1 примечателен по нескольким причинам. Во-первых, здесь используются отладочные стили, так что вы можете посмотреть на часть внутренней структуры этих тегов. Во-вторых, этот снимок сделан с использованием Mozilla 1.0.2. В этой версии присутствует поддержка grippys панелей инструментов, которой нет в версии 1.2.1. В-третьих, в некоторых местах, где не должно быть тегов, были добавлены теги <description>. Эти теги, содержащие текст в фигурных скобках на светлом фоне, показывают положение неотображаемых тегов-контейнеров.

    У всех тегов на этом рисунке есть XBL-определения. На рисунке 8.2 показан тот же документ, что и на рисунке 8.1, только без отладочной информации.

    XUL-теги для навигации

    Рис. 8.2.  XUL-теги для навигации

    8.2.1. Элементы управления прокруткой

    Можно создавать XML-содержимое, которое по размерам превышает пределы текущего окна или экрана. Такое содержимое обычно обрезается по границе текущего окна. HTML и XUL предоставляют полосы прокрутки, которые позволяют пользователю перемещать содержимое внутри области усечения. Это команда перемещения текущего представления, основанная на жесте мышью или нажатии клавиш. Такие действия по перемещению реализуются напрямую и HTML, и XUL. В XUL есть следующие теги, обеспечивающие возможность выполнения действий прокрутки:

    <arrowscrollbox> <scrollbar> <nativescrollbar> <scrollbox>
    

    Реализация HTML в Mozilla поддерживает тег <MARQUEE>, чье XBL-определение можно найти в chrome. Этот тег позволяет анимировать прокрутку своего содержимого.

    XUL также поддерживает свойства стилей overflow:scroll и overflow:auto из CSS 2. Это самые быстрые способы предоставить простую прокрутку содержимого. Однако некоторые расширения CSS 2 дополняют эти функции (см. раздел "Альтернатива: таблицы стилей" далее в этой главе).

    8.2.1.1. <scrollbox>

    Тег <scrollbox> может выглядеть как окончательное решение проблемы прокрутки, но это не так. Тег <scrollbox> не предоставляет графических элементов управления. Он ведет себя так же, как и тег <box>, только дополнительно реализовывает интерфейс nsIScrollBoxObject. Как и тег <box>, он поддерживает следующие атрибуты размещения:

    orient align pack dir maxwidth maxheight minwidth minheight
    

    Этот тег похож на <box>, потому что он узкоспециален. Это первый рассматриваемый в книге тег, который является специализацией общего объекта <box>.

    В главе 2, "Проектирование с XUL", говорилось о том, что блоки реализуются поверх модели более низкого уровня, которая называется фреймом. Фрейм - это всего лишь область на экране, которая обрабатывается отдельно. <scrollbox> задуман так, чтобы отображать свое содержимое со смещением относительно фрейма на данные значения по x и по y. Вот и все.

    XUL не предоставляет никаких особенных функций для <scrollbox>, но у этого тега есть несколько доступных из скриптов методов объекта. Эти методы добавляются интерфейсом nsIScrollBoxObject. Каждый вызов одного из методов перемещает отображаемое содержимое в новую позицию во фрейме. При этом можно указывать значения напрямую в пикселах или в других единицах измерения. Например, методы, содержащие в своем имени "line", перемещают содержимое вертикально на указанное число строк. Методы, содержащие в своем имени "index", перемещают содержимое вертикально на высоту заданного числа тегов содержимого. Если эти методы используются многократно, содержимое будет прокручиваться в данном направлении (вверх и вниз, вперед и назад или любым другим анимированным движением).

    Эти дополнительные методы отсутствуют в DOM-объекте тега <scrollbox>. Как и у любого другого блочного XUL-тега, у <scrollbox> есть свойство boxObject. Это свойство boxObject - объект, содержащий все состояния тега блока (например, положение и размер). Он также содержит метод QueryInterface(), который используется для получения XPCOM-интерфейсов. Если данный тег - <scrollbox>, тогда с помощью данного метода можно получить методы интерфейса nsIScrollBoxObject. Это единственный способ обратиться к указанному интерфейсу.

    Это означает, что если тегу <scrollbox> нужно что-то делать, он должен управляться каким-то скриптом, написанным самим программистом. Он полезен только для программистов, создающих собственные элементы управления.

    Простой пример можно найти в файле scrollbox.xml chrome из архива toolkit.jar. XBL-связка с именем autorepeatbutton извлекает интерфейс nsIScrollBoxObject из находящегося рядом содержимого <scrollbox> и манипулирует этим содержимым через полученный интерфейс так, что оно прокручивается вверх и вниз. Фрагмент этого кода показан в листинге 8.1.

    <handler event="command">
    <![CDATA[ 	... часть кода пропущена ... 
      var dir = this.getAttribute("scrolldir"); 
      var bx = this.mScrollBox.boxObject.QueryInterface
       (Components.interfaces.nsIScrollBoxObject); 
      bx.scrollByIndex(dir == "up" ? -1 : 1); ]]> 
    </handler>
    
    Листинг 8.1. Пример XUL-блока со вкладками

    В этом листинге говорится, что событие команды <autorepeatbutton> приводит к тому, что содержимое тега <scrollbox> (который, предположительно, находится рядом) прокручивается за раз на одну строку. Так как этот тип кнопки непрерывно создает события, пока она нажата, содержимое <scrollbox> также прокручивается непрерывно. <autorepeatbutton> - это визуальный тег, управляющий тегом <scrollbox> через особый интерфейс nsIScrollBoxObject.

    Вы можете изучить эту связку, если хотите создать собственный элемент управления, основывающийся на <scrollbox>. Однако нужно помнить, что <scrollbox> в одном отношении необычен. Этот тег ожидает, что его содержимым будет единственный тег <box>, а все действительно значимое содержимое будет находиться внутри <box>. Это сложнее, чем случай, когда свойство boxObject принадлежит самому внешнему DOM-объекту тега.

    Подведем итог. Тег <scrollbox> - фундаментальный тег, который должен окружаться другими тегами и снабжаться скриптами, прежде чем он сможет действительно стать решением проблемы прокрутки. К счастью, есть и другие способы быстро создать прокручивающийся блок.

    8.2.1.2. Тег <arrowscrollbox>

    Тег <arrowscrollbox> - это компонент для создания тега <menupopup>, строящийся, в свою очередь, на основе других тегов. В листинге 8.2 показана иерархия тегов, образующих <arrowscrollbox>. Обратите внимание, что это не действительная часть XML-листинга, а просто структурная схема содержимого тега.

    <arrowscrollbox> <autorepeatbutton> <image> <scrollbox> 
    <box> <что-то> <что-то> ... <autorepeatbutton> 
    <image>
    
    Листинг 8.2. Схема тега <arrowscrollbox>

    Если содержимое <box> превышает размеры <arrowscrollbox>, появляются две кнопки <autorepeatbutton>. Если все содержимое умещается в самый внешний тег, тогда эти два тега скрыты. Это обычная ситуация для меню и поэтому нет никакого указателя на то, что <arrowscrollbox> существует в каждом меню, даже если это так. Этот тег также может использоваться самостоятельно, отдельно от всех меню. У него есть чрезвычайно простое XBL-определение, с которым легко экспериментировать.

    8.2.1.3. Тег <scrollbar>

    Тег <scrollbar> предоставляет одиночную вертикальную или горизонтальную полосу прокрутки, которая не зависит от окружающего содержимого. Если такая полоса должна что-то прокручивать, она должна координировать это содержимое с помощью JavaScript. В листинге 8.3 показана структурная схема тега <scrollbar>.

    <scrollbar> <scrollbarbutton> <image> <scrollbarbutton> <image> <slider> 
    <thumb> <gripper> <scrollbarbutton> <image> <scrollbarbutton> <image>
    
    Листинг 8.3. Схема тега <scrollbar>

    Тег <scrollbar> в сумме содержит четыре кнопки. Так как две из них предназначены для вертикальных полос прокрутки, а две - для горизонтальных, одна пара из них всегда скрыта с помощью стилей CSS 2. Это делается в XBL-определении <scrollbar>. Чтобы увидеть данную структуру, можно воспользоваться инспектором DOM.

    <scrollbar> поддерживает атрибут orient, который задает вертикальное или горизонтальное направление прокрутки. Другие XUL- атрибуты, характерные для <scrollbar>, соответствуют атрибутам тега <slider>. Тег <slider> никогда не должен использоваться вне тега <scrollbar>. Вот эти общие атрибуты:

    curpos maxpos pageincrement increment
    

    Эти четыре атрибута моделируют текущую позицию ползунка одним числом. Это число представляет позицию центра ползунка, и эта позиция относительна. При растягивании окна ее значение не изменится, если только не изменится число видимого содержимого. Диапазон значений - от 0 до maxpos, текущее значение - curpos.

    Иногда атрибут curpos доступен в скриптах как DOM-свойство, но стабильная работа не гарантирована, и на это не стоит полагаться - всегда следует пользоваться методами setAttribute() и getAttribute(). increment - самое большое изменение, вызываемое нажатием <scrollbarbutton>; pageincrement - самое существенное изменение, вызываемое нажатием на саму полосу прокрутки, по которой перемещается ползунок. Эти два действия могут вызывать и меньшее изменение значения позиции, если ползунок находится вблизи от одного из концов полосы прокрутки.

    Другие аспекты тега <scrollbar> полностью зависят от стилей. Чтобы увеличить или уменьшить полосу прокрутки, примените к ней стили CSS 2. Вам придется самостоятельно проводить расчеты, если вы хотите, чтобы размер ползунка соответствовал видимой части содержимого. Чтобы автоматически получать подходящие размеры ползунка, следует или сделать значение maxpos маленьким относительно размера полосы прокрутки, что позволяет менять стили ползунка, или пользоваться полосой прокрутки на основе CSS вместо тега <scrollbar>. О последнем варианте рассказано в разделе "Альтернатива: таблицы стилей". Размер ползунка при использовании стандартного <scrollbar> не особенно важен.

    8.2.1.4. Тег <nativescrollbar>

    XUL разбивает полосу прокрутки на множество частей, но это единственный способ реализовать такой элемент управления. Многие библиотеки графических элементов могут предоставлять элемент управления как единый целый объект, а не набор его составляющих, которые приложение должно связать друг с другом. Тег <nativescrollbar> предназначен для отображения всей системной полосы прокрутки как одного объекта. Его использование пока что ограничено только платформой, и он применяется только при выборе тем, соответствующих теме графической среды.

    Не пользуйтесь <nativescrollbar>, если только вы не работаете преимущественно с собственными темами графической среды или встраиваете Mozilla в какое-то другое графическое приложение.

    8.2.2. Панели инструментов

    Панель - это прямоугольная область окна, заполненная элементами управления. Панели инструментов и строки меню обычно появляются вдоль краев окна приложения, чаще всего вдоль верхнего края. Они предоставляют место для удобного запуска команд пользователем. Чтобы увидеть панели инструментов в Mozilla, нужно просто открыть окно классического браузера и взглянуть на его верхнюю часть. В классическом браузере есть дополнительная функциональность, позволяющая сворачивать и снова разворачивать панели инструментов. Попробуйте поэкспериментировать с подменю Вид | Показать/скрыть (View | Show/Hide).

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

    Панели инструментов Mozilla просты. По умолчанию их нельзя перетаскивать и закреплять у края, как панели инструментов в Netscape 4.x или в приложениях Microsoft. Их также нельзя прикреплять друг к другу или отделять от них части. К тому же панели инструментов Mozilla нельзя располагать вертикально. Они не предоставляют пиктограмму ("Больше"), которая появляется на панелях инструментов Internet Explorer [прим. пер.: уже предоставляют, например, в закладках на Личной панели]. Почти все эти функции при желании можно добавить к предоставленным базовым панелям инструментов.

    У панелей Mozilla есть несколько преимуществ. Доступны grippys для сворачивания панелей инструментов из Netscape 4.x (но не в версии 1.2). Если они есть, панели инструментов могут быть закреплены на одном месте путем скрытия grippys с помощью стилей. Когда grippys панелей инструментов не поддерживаются, панели инструментов всегда закреплены на одном месте. Закрепленные панели инструментов - идея, заимствованная из Internet Explorer 6. Панели инструментов Mozilla также могут появляться в любом месте окна приложения, а так как для их создания используется XUL, организовать это очень просто.

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

    Особенности панелей инструментов в теме Modern

    Рис. 8.3.  Особенности панелей инструментов в теме Modern

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

    8.2.2.1. Тег <toolbox>

    Тег <toolbox> - это контейнер для набора панелей инструментов. Его XBL-связка находится в файле toolbar.xml в chrome. Если grippys панелей инструментов отсутствуют (как в Mozilla 1.2.1), он ведет себя как <vbox>. И в ранних, и в последних версиях, где grippys снова поддерживаются, содержимое тега соответствует структурной схеме, показанной в листинге 8.4.

    <toolbox> <vbox> <toolbar или menubar> <toolbar> 
    ... еще панели инструментов ... <hbox> <hbox> <spacer>
    
    Листинг 8.4. Схема тега <toolbox>

    Хотя в данном <toolbox> может быть несколько тегов <menubar>, это не очень хорошая практика, так как при навигации с клавиатуры возникает неопределенность.

    Программист приложения указывает только тег <toolbox> и содержащиеся в нем <toolbar> и <menubar>; все остальное создается автоматически. <vbox> содержит панели инструментов; <hbox> содержит пустой <hbox> и <spacer> с атрибутом flex. Этот пустой <hbox> нужен для хранения изображений, представляющих свернутые панели инструментов. Теги изображений не создаются заранее и скрываются с помощью стилей CSS 2, так как число панелей инструментов изначально неизвестно. Вместо этого они создаются динамически JavaScript-обработчиками onclick в XBL-определении.

    Там, где нет grippys, <toolbox> - не более чем объект для применения стилей. Внутри него может находиться любой тег, но <toolbar> и <menubar> должны быть его непосредственными потомками.

    8.2.2.2. Тег <toolbar>

    Тег <toolbar> - первый из двух вариантов содержимого <toolbox>. Он представляет собой одну горизонтальную панель управления, которая ведет себя как <hbox> и ничем не примечательна. Эта панель может включать в себя любой тип содержимого. Единственные особо интересные XML-атрибуты:

    collapsed grippyhidden grippytooltiptext
    

    collapsed со значением true свернет панель инструментов, как и любой другой тег, grippyhidden со значением true закрепит панель на одном месте, скрывая <toolbargrippy>, который по умолчанию есть у каждой панели. grippytooltiptext задает текст всплывающей подсказки для grippy. Этот текст появляется, когда панель свернута, а указатель мыши находится над оставшейся видимой grippy.

    Задание атрибута collapse и нажатие на grippy - не одно и то же. Чтобы эмулировать последнее действие, нужно вызвать метод collapseToolbar() родительского тега <toolbox>, передав как единственный аргумент DOM-объект <toolbar>.

    Ранние версии Mozilla включали начальное изображение или пиктограмму для всей панели инструментов, но в последних версиях это было убрано. Тем не менее, такое изображение по-прежнему можно добавить с помощью свойства CSS 2 list-style-image.

    Недостаток тега <toolbar> заключается в том, что он не всегда размещается правильно. Проблемы могут возникать, если он занимает меньше полной ширины XUL-окна. Если тег появляется в правой части внешнего <toolbox>, а окно узкое, содержимое <toolbar> может быть усечено некорректно. Иногда это работает, иногда нет. Чтобы достичь наилучшего результата, следует просто сделать <toolbar> шириной во все окно приложения.

    В главе 5, "Скрипты", рассматривается grippy панели инструментов, реализуемой с помощью <toolbargrippy>. grippy представляет собой простое изображение; идея этого элемента управления была позаимствована из графической среды OpenLook от Sun Microsystem.

    Так как панели инструментов можно создавать динамически, лучше всего задавать простую структуру их содержимого. Сделайте все элементы на панели инструментов непосредственными потомками тега <toolbar>.

    8.2.2.3. Теги <toolbaritem>, <toolbarbutton> и <toolbarseparator>

    Теги <toolbaritem>, <toolbarbutton> и <toolbarseparator> используются как содержимое <toolbar>. <toolbaritem> - анонимный тег. <toolbarseparator> - анонимный тег со стилями, предоставляющими дополнительное место и возможность применения стилей далее. <toolbarbutton> - кнопка. Последние два описаны в главе 4, "Первые элементы управления и темы".

    Хотя у двух из этих тегов нет особых свойств, у них есть цель. Когда для создания панелей инструментов используются шаблоны, система шаблонов определяет, как создавать содержимое, основываясь на имени тегов. Хотя у <toolbaritem> нет собственного особого значения, система шаблонов может распознать имя и пропустить его. Это позволяет использовать тег в качестве контейнера для какого-то содержимого, которое не должно обрабатываться.

    Всплывающие подсказки для кнопок и других тегов описываются в главе 10, "Окна и панели".

    8.2.3. Строки меню

    XUL в Mozilla поддерживает строки меню, которые являются особой формой панелей инструментов. Общепринято, что строка меню должна быть первой панелью инструментов в <toolbox>, так чтобы она появлялась в верхней части группы панелей.

    8.2.3.1. <menubar>

    Этот тег ведет себя как обычный <hbox> и может появляться внутри тега <toolbox> или вне его. Внутри <toolbox> может быть несколько <menubar>. Это общий случай.

    Платформа Macintosh, и MacOS 9, и X, - особый случай. На этой платформе существует единственная строка меню, которая динамически разделяется между всеми запущенными приложениями. Эта особая строка меню существует вне основной системы управления окнами. Содержимое тега <menubar> применяется к такой строке меню в Macintosh, и это содержимое появляется только в данной строке. При этом считывается только один тег <menubar>, а в строку меню попадают только его потомки <menu>. Эти меню появляются на строке меню, когда окно Mozilla получает фокус. Они не появляются внутри окна Mozilla.

    На других платформах <menubar> можно заполнять любым содержимым.

    Тег <menubar> поддерживает специальные возможности Mozilla. Особые атрибуты <menubar> такие же, как и у <toolbar>:

    collapsed grippyhidden grippytooltiptext
    

    В Macintosh эти атрибуты не делают ничего. XBL-определение Mozilla для <menubar> находится в файле chrome toolbar.xml.

    8.2.3.2. <menu>

    Тег <menu> - единственный тег, который должен появляться внутри <menubar>. Он реализует метки, которые ведут себя как кнопки и при нажатии отображают выпадающие меню. Это интерфейс для тега <menupopup>, похожий на другие теги-интерфейсы, описанные в главе 6, "События". Тег <menu> также может использоваться вне <menubar> как элемент формы (хотя для этого лучше применять <menulist>) или как меню, вложенное в другое. Если у тега <menu>, непосредственного потомка <menubar>, нет содержимого, он будет во многом похож на <toolbarbutton>; в таком случае следует использовать вместо него <toolbarbutton>.

    Тег <menu> поддерживает специальные возможности Mozilla и допускает следующие особые атрибуты:

    disabled _moz-menuactive open label accesskey crop acceltext image
    

    disabled со значением true делает меню недоступным. _moz-menuactive со значением true применяет стиль, который выделяет заголовок меню, как если бы это была кнопка. open со значением true может применять к заголовку меню и другие стили, а также указывает на то, что выпадающее меню отображено. Другие атрибуты относятся к вложенным тегам <label>, кроме image, который относится к необязательной, но иногда доступной пиктограмме. Все теги с содержимым, создающиеся автоматически, описываются в разделе "Варианты меню".

    Атрибут _moz-menuactive передается через тег <menu> от родительского тега <menubar> дальше до тегов <menuitem>, которые составляют содержимое меню. На этом атрибуте основаны многие стили. Эти стили предоставляют визуальную реакцию на действия пользователя при навигации по структуре меню. Атрибут _moz-menuactive мог бы называться -moz-menuactive, но имена XML-атрибутов не могут начинаться со знака "-". Имя этого атрибута еще может измениться, так что проверьте XBL-файлы в своей версии платформы, чтобы узнать, осталось ли оно прежним.

    <menupopup> и <template> - единственные теги, которые могут быть содержимым тега <menu>. Как и панели инструментов, содержимое меню может создаваться системой шаблонов XUL или системой оверлеев. Таким же образом могут создаваться и отдельные меню, а не вся система меню.

    <menu> также может использоваться внутри тега <toolbar>, но это делать не рекомендуется.

    8.2.3.3. Варианты меню

    У различных XUL-тегов, элементов форм, например, <button> и <textbox>, есть разные варианты, определяющиеся атрибутом type. У тега <menu> также есть варианты, но они определяются атрибутом class. Значение этого атрибута соответствует стандартным правилами стиля, задающим XBL-связку, которая будет применена к тегу <menu>. Доступны несколько связок, и каждая из них предоставляет свое содержимое по умолчанию.

    В сумме существует пять незначительно отличающихся друг от друга вариантов меню. Эти варианты влияют только на исходное представление тега <menu>, но не на последующий открывающийся тег <menupopup>. Атрибут class может быть не задан; его значением может быть menu или menu-iconic (три варианта). Тег <menu> может находиться внутри или снаружи тега <menubar> (два варианта). 2x3=6 вариантов, но два из них идентичны. На рисунке 8.4 показаны эти варианты с отладочными стилями.

    Варианты тега <menu>

    Рис. 8.4.  Варианты тега <menu>

    Верхняя строка на этом снимке - <menubar>. Нижняя - <hbox>. Атрибуты accesskey и acceltext меняются, просто чтобы проиллюстрировать некоторые сочетания. Стоит обратить внимание на наличие и отсутствие тегов содержимого <label> и <image>, которое отмечено на рисунке черной прерывистой и тонкой черной сплошной линиями соответственно.

    В этом примере у всех тегов меню есть атрибут maxwidth="150px", используемый для демонстрации выравнивания. Теги внутри строки меню (<menubar>) выровнены влево, а теги вне ее - вправо. Слова "no class" (класс не задан), "menu" и "menu-iconic" - заголовки каждого из шести отображаемых меню - соответствуют значению атрибута class тега <menu>. Любой второй <label> справа содержит текст атрибута acceltext.

    Добавление пиктограмм в меню <menubar> - не очень сложная задача. Для начала следует задать атрибут class="menu-iconic". Если <menu> находится вне строки меню, можно использовать атрибут image, но если меню находится внутри строки, никакого эффекта от этого атрибута не будет. Чтобы пиктограмма появилась, нужно определить свой класс для тега <menu> (или использовать любой другой) и добавить в документ следующий собственный стиль:

    .menubar-left#X {list-style-image: url("icon.png");}
    

    X - идентификатор тега <menu>, которому нужна пиктограмма. Добавляйте по одному правилу для каждого меню, где должна появляться пиктограмма. Это не лучшее решение, но пока оно работает.

    8.2.4. Строки состояния

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

    XBL-определения тегов, поддерживающих строки состояний, хранятся в файле chrome general.xml архива toolkit.jar.

    8.2.4.1. <statusbar>

    Тег <statusbar> представляет горизонтальную область, как и <toolbar>, но <statusbar> не ведет себя как <hbox>. Следовательно, содержимое этого тега может появляться справа. В обычной ситуации <statusbar> должен растягиваться до полной ширины окна Mozilla. Внутри <statusbar> может быть любое содержимое. Тег <statusbar> существует как удобное средство для браузера Mozilla. Это не фундаментальная составляющая, а, скорее, тег уровня приложения. Он предоставляет стили и немного особого содержимого. У него нет специальных атрибутов.

    Возвращаясь к рисунку 8.3, <statusbar> появляется как "вдавленная" область окна, в которую может добавляться содержимое. Внешний вид этой области есть результат примененных стилей. Если вы хотите, чтобы размеры XUL-окна можно было менять на Macintosh, тогда добавление тега <statusbar> в низ документа - простейший способ гарантировать это, потому что в правом конце строки состояния находится тег <resizer>.

    Соблазн использовать сразу несколько тегов <statusbar> один за другим достаточно велик, но на Macintosh это будет выглядеть странно. В таком случает появится несколько пиктограмм <resizer>, так что не стоит этого делать.

    8.2.4.2. <statusbarpanel>

    Внутри <statusbar> может появляться любое содержимое, но лучше сгруппировать это содержимое в набор тегов <statusbarpanel>. Этот тег копирует внешний вид тега <button>, но это не кнопка и обычно он не нажимается. Этот тег просто разделяет строку состояния в нижней части любого окна браузера Mozilla на визуальные отделения. Все это делается с помощью стилей; у <statusbarpanel> нет специального поведения элементов управления, он ведет себя как <hbox>.

    Внутри <statusbarpanel> может быть любое содержимое XUL. С другой стороны, его внешний вид может определяться атрибутами. Вот особые атрибуты <statusbarpanel>:

    src label crop
    

    Существует два варианта этого тега. Если задан атрибут class="statusbarpaneliconic", тогда его содержимое - одно-единственное изображение, задаваемое атрибутом src. Иначе содержимое - единственная надпись, к которой относятся атрибуты label и crop. Если <statusbarpanel> содержит что-то нестандартное, определенное пользователем, тогда такое содержимое может замещать эти атрибуты.

    Пользуйтесь <statusbarpanel>, чтобы выделить управляющую область в отображаемом XUL-документе. Этот тег может появляться вне тега <statusbar>, но результат такого применения не определен.

    8.2.5. Строки заголовков

    В XUL Mozilla предусмотрена некоторая поддержка строк заголовков. В большинстве случаев строка заголовка - это часть окна, добавляемая, как и другие обрамления окна, менеджером окон графической среды. В XUL реализована лишь частичная поддержка работы с такими строками. Строке заголовка не соответствует фрейм.

    Простейший способ задать содержимое строки состояния - использовать свойство window.title. Каким бы ни было его значение, оно появится в основной части строки заголовка. Другие элементы строки заголовка недоступны, хотя в окне, основанном на теге <dialog>, можно удалить некоторые элементы управления. Окно можно открыть и без строки заголовка вообще, передавая параметры функции window.open() (см. подробнее в главе 10, "Окна и панели").

    В chrome Mozilla содержится XBL-определение тега <titlebar>. Он иногда встречается в других XBL-определениях, но у него нет статуса настоящего XUL-тега. Это не более чем <hbox>, содержащий <label> и <image>. Он должен моделировать строку состояния, добавляемую к окну менеджером окон графической среды. Это составная часть тега <floatingview>, описываемого далее. При желании можно изучить его применение подробнее.

    Тег <dialogheader> не имеет ничего общего со строками заголовков, это просто контейнер для некоторого содержимого.

    window.open(), <dialog>, <dialogheader> и <page> описываются в главе 10, "Окна и панели".

    8.2.6. Отображение окон с несколькими секциями

    Что делать, если все XUL-содержимое не помещается на площадь одного экрана целиком? XUL предоставляет несколько методов для решения этой задачи, основанных на идее "заталкивания" большего содержимого в одно окно. Каждая составная часть окна называется панелью, хотя этот термин и не совсем технически точен. Некоторые особенности панелей рассматриваются в главе 10, "Окна и панели". Простейший способ отобразить дополнительное содержимое - пользоваться полосами прокрутки, но это упрощенное решение. Лучшим решением будет проверить дизайн окна вашего приложения. У большинства окон должны быть простые цели или цель, и пользователям не нужно много перемещаться по ним. Никто никогда не должен прокручивать содержимое окна приложения вниз, чтобы обнаружить "дополнительные" элементы формы. Это может быть уместно на web-страницах, но, в конце концов, это признак плохого проектирования. Формы всегда должны умещаться в изначально отображаемое окно.

    Некоторые приложения ориентированы на работу с объектами, как рабочие столы. Обычно опытные пользователи таких приложений не нуждаются в упрощенном дизайне. Если дизайн упростить невозможно, XUL предоставляет разделители и вкладки для разделения содержимого на части. И те, и другие разбивают содержимое окна на секции, возлагая на пользователя ответственность за переход между этими секциями вручную. Преимущество такого разделения - более корректное упорядочивание содержимого; цена - появление дополнительных элементов управления навигацией, которые не связаны с основной целью приложения.

    Другие приложения совсем не похожи на рабочие столы. В случае часто используемых приложений, например, форм ввода данных, введение разделителей и вкладок может заметно ухудшить производительность. Пользуйтесь этими методами, только если ожидаете, что пользователи обдумают свои действия, упорядочивая содержимое окна. Не пользуйтесь ими в уже устоявшихся приложениях и пилотных демонстрациях приложений. Это не заменит хорошего проектирования. Лучше сделать действительной целью поддержку приложения, а не создавать "швейцарский нож", подходящий для любых целей. Однако этот совет не относится к области конкурентоспособных продаж. В области продаж важнее поразить аудиторию "спецэффектами", чем произвести что-то действительно надежное и удобное в использовании. Такова жизнь.

    Если существует риск, что у пользователей будет слишком маленькое экранное разрешение, тогда разделители и вкладки могут помочь. Такой риск должен рассматриваться как ограничение в проектировании на высоком уровне. И для его снижения не нужно нашпиговывать окно дополнительными разделителями и вкладками.

    В главе 10, "Окна и панели", мы продолжим тему упорядочивании содержимого, которое нельзя уместить в одно окно. Другая методика многопанельного отображения в XUL - тег <wizard>, рассматриваемый в главе 17, "Система распространения и установки - XPInstall".

    8.2.6.1. Тег <splitter>

    Тег <splitter> ведет себя как смесь тегов <button>, <resizer> и <spacer>. Пример на рисунке 8.3 несколько нетипичен, потому что разделители обычно довольно узки, так что могут занимать минимальную площадь на экране.

    В одном XUL-документе может быть несколько тегов <splitter>. Разделители обширно используются в отладчике JavaScript Mozilla и отделяют боковую панель от содержимого web-страницы в окне навигатора. Цель разделителя - разбивать содержимое на две панели, по одной с каждой стороны.

    Тег <splitter> обычно содержит один тег <grippy>. Как говорилось в главе 4, "Первые элементы управления и темы", на тег <splitter> можно нажимать и его можно перетаскивать с помощью тега <grippy>. Тег <grippy> предоставляет область для хранения обработчиков событий и стилей; вот и все, что он делает. Использовать его очень просто:

    <splitter><grippy/></splitter>
    

    При необходимости тег <grippy> можно опустить.

    Тег <splitter> работает следующим образом: он и другие теги на одном с ним уровне содержатся в <vbox>, <hbox> или теге, похожем на блочный. Когда пользователь щелкает по разделителю и перетаскивает его, разделитель пересчитывает свое положение, основываясь на каждом малейшем смещении при движении. Затем он отдает команду своим "соседям" сжаться или растянуться. Сам разделитель не меняет размера, и в обычном случае родительский <vbox> или <hbox> также остается того же размера. Как будут сжиматься или растягиваться "соседи", зависит от атрибутов тега <splitter>. Если в родительском теге несколько разделителей, тогда каждый действует независимо от других, считая остальные обычным содержимым.

    Вот атрибуты с особым значением в сочетании с тегом <splitter>:

    orient disabled collapse state resizebefore resizeafter fixed
    

    Атрибут orient определяет, будет разделитель вертикальным (vertical) или горизонтальным (horizontal). disabled со значением true заставляет разделитель перестать реагировать на действия пользователя. collapse определяет, какой "сосед" разделителя (before или after) должен исчезнуть, если разделитель свернут. Значением state может быть open, dragging или collapsed. open означает, что содержимое обоих "соседей" разделителя видимо. dragging означает, что пользователь производит жест мышью, начавшийся с разделителя, а collapsed значит, что содержимое одного из "соседей" разделителя полностью скрыто, а все доступное место занимает другая панель.

    Чтобы сворачивание разделителя работало, у <splitter> должен быть "сосед" с той стороны, куда будет производиться сворачивание. Простейший способ сделать это - использовать на этой стороне тег <box>. Сворачивание происходит, только если задан атрибут state - это делается с помощью JavaScript в реализации <grippy>. Обратите внимание, что state="collapsed" и collapse="..."[/отличаются от стандартного атрибута [mllapsed="true", доступного во всех XUL-тегах. collapsed="true" в сочетании со <splitter> спрячет сам разделитель.

    Оставшиеся атрибуты определяют, как будут меняться размеры прилегающего к разделителю содержимого. Если значение resizebefore или resizeafter - farthest, тогда сужающаяся панель будет сначала отбирать место у самого дальнего "соседа" тега <splitter>. Если значение - closest, тогда она будет начинать с ближайшего "соседа". Если сужающаяся панель содержит единственный <box>, тогда его содержимое будет сужаться равномерно, не обращая внимания на атрибуты resizebefore или resizeafter. Значением resizeafter также может быть grow. В этом случае содержимое после разделителя не будет уменьшаться, когда разделитель будет перетаскиваться в его сторону. Вместо этого оно будет перенесено в сторону так, что выйдет за пределы блока-контейнера или границ окна и будет усечено. Задание атрибуту fixed значения true перекрывает другие параметры и не дает перемещать grippy. Тем не менее, разделитель по-прежнему можно будет сворачивать.

    Этот набор параметров означает, что атрибуты state и resizebefore/resizeafter не могут использоваться все сразу, так как они требуют различного размещения прилегающего содержимого. Смешивание правил изменения размеров с атрибутом flex и изменением размеров окна может произвести целый ряд слегка отличающихся друг от друга эффектов.

    У <splitter> есть один вариант: он также отвечает за изменение размеров столбцов в теге <tree>. В этом случае у него есть атрибут class="tree-splitter" и отсутствует видимое представление. См. лекцию 13, "Списки и Деревья".

    8.2.6.2. Тег <tabbox>

    Система вкладок в XUL - способ предоставить многодокументный интерфейс в Mozilla; <tabbox> - необходимый для этого тег самого верхнего уровня. Такой интерфейс позволяет нескольким документам отображаться в одном окне. В случае Mozilla эти документы могут быть маленькими - один XUL-тег - или, при добавлении тега <iframe>, большими документами. <iframe> описывается в главе 10, "Окна и панели"; здесь рассматривается общее представление документов в виде вкладок.

    Пример типичного использования вкладок приведен в листинге 8.5. Автор приложения должен предоставить большую часть содержимого для вкладок, как и для <arrowscrollbox> и <scrollbar>. Как обсуждалось ранее в этой главе, это не дело тегов.

    <tabbox> 
      <tabs> 
        <tab id="t1" label="First" selected="true"/> 
        <tab id="t2" label="Second"/> 
      </tabs> 
      <tabpanels> 
        <tabpanel> 
          <description>Panel 1 content</description> 
        </tabpanel> 
        <tabpanel> 
          <description>Panel 2 content</description> 
        </tabpanel> 
      </tabpanels> 
    </tabbox>
    
    Листинг 8.5. Пример XUL-вкладок

    Чтобы все координировалось правильно, число тегов <tabpanel> должно соответствовать числу тегов <tab>. Любой XUL-тег может заменять <tabpanel>, хотя этот тег - очевиднейший способ создать блок со вкладками. На рисунке 8.5 показано, как стандартные атрибуты размещения dir и orient могут использоваться с тегами <tabbox> и <tabs> для изменения стандартного внешнего вида блока.

    Варианты ориентирования вкладок

    Рис. 8.5.  Варианты ориентирования вкладок

    Очевидно, что вкладки Mozilla не так гибки, как можно было надеяться; только самое распространенное, обычное размещение выглядит нормально. Чтобы довести остальные варианты до ума, пришлось бы использовать множество дополнительных стилей, но затраты здесь достаточно велики, так что идти на это рекомендуется только в особых случаях. Примеры особых случаев можно найти в классическом компоновщике и классическом IRC-клиенте.

    Тег <tabbox> - обычный блочный тег. У него есть поддержка специальных возможностей и много обработчиков событий клавиатуры для клавиш, с помощью которых можно перемещаться по блоку. Его XBL-определение, а также определения других относящихся к нему тегов, можно найти в файле tabbox.xml архива toolkit.jar chrome. У него нет атрибутов с особым значением, но доступны следующие JavaScript-свойства:

    selectedIndex selectedTab selectedPanel accesskey
    

    selectedIndex - номер текущей выбранной вкладки, начиная с 0 (нуля) для первой. selectedTab и selectedPanel указывают на DOM-объекты для <tab> и <tabpanel>, соответствующих номеру выбранной вкладки. accesskey предоставляет поддержку специальных возможностей для всего блока со вкладками.

    У DOM-объекта <tabbox> также есть несколько полезных методов. Взгляните на теги <method> в связке "tabbox" соответствующего XBL-файла, чтобы узнать их имена, параметры и случаи использования.

    <tabpanels> - вариант тега <deck>; все остальные теги, связанные в Mozilla со вкладками, не обладают особым значением, как элементы управления. Они все состоят из обычных блоков, стилей и XBL-определений.

    8.2.6.3. Теги <tabs> и <tab>

    Тег <tabs> - обычный блочный тег. Он содержит набор тегов <tab> плюс несколько скрытых тегов <spacer>, которые нужны на каждом конце строки вкладок для применения стилей. В стандартных темах Mozilla вкладки не могут накладываться друг на друга (как, например, корешки листов в Microsoft Excel), но можно создать сложные и, возможно, ненужные стили для получения такого эффекта, если это необходимо.

    Тег <tab> - также простой блочный тег. Его скругленные уголки - результат использования расширений стилей Mozilla для границ, описанных в главе 2, "Проектирование с XUL". Содержимое этого тега может быть любым. Если оно отсутствует, тогда для указания надписи и пиктограммы можно использовать следующие атрибуты:

    image label accesskey crop disabled
    

    Эти атрибуты действуют так же, как и в случае тега <button>. У DOM-объекта тега <tab> есть булево свойство selected, которое принимает значение true, если вкладка выбрана.

    Теги <tabs> и <tab> можно использовать вне <tabbox>, но делать это бессмысленно, потому что без дополнительных усилий программиста они не будут нормально работать.

    8.2.6.4. Теги <tabpanels> и <tabpanel>

    Тег <tabpanels> - <deck>. Каждый тег <tabpanel> - одна карта в колоде, которая открывается при щелчке по соответствующему тегу <tab>. У этих тегов есть поддержка специальных возможностей и несколько XBL-обработчиков событий для навигации с клавиатуры; во всем остальном они ничем не примечательны.

    XUL - не HTML, и в нем можно полностью спрятать элементы формы, поместив их во вкладку, которая не находится наверху. В HTML у элементов формы всегда наибольшее значение CSS-свойства z-index, которое невозможно перекрыть.

    8.2.6.5. Другие системы панелей

    Сочетание XUL, JavaScript и XBL предоставляет множество возможностей для создания систем отображения, которые могут скрывать и показывать содержимое в виде панелей. Кроме XUL-тегов, рассмотренных к этому моменту, в классическом браузере есть несколько созданных для специальных целей систем отображения панелей.

    <multipanelset> и <multipanel> - теги, специфичные для инспектора DOM. Это определенные автором приложения теги на основе XBL. Соответствующие XBL-определения хранятся в chrome инспектора DOM, а не в общем chrome приложений. На рисунке 8.6 эти теги показаны в действии.

    Содержимое <multipanel> в инспекторе DOM

    Рис. 8.6.  Содержимое <multipanel> в инспекторе DOM

    На снимке показано окно инспектора DOM, отображающее правую панель с описанием XBL-связок. Все содержимое ниже <textbox> со строкой URL chrome://global/...[/ содержимое [multipanelset>[/ занимающее всю оставшуюся часть правой панели. Внутри этой области разбросаны шесть тонких горизонтальных полос. Каждая из них выглядит немного похожей на <splitter>; на снимке они чуть затемнены, чтобы сделать их более заметными. Взгляните на содержимое этой правой панели: одна полоса находится вверху, одна - внизу, и две группы по две - между ними. Каждая из этих полос - <multipanel>, и у каждой может быть собственное, определенное автором приложения содержимое. Это содержимое появляется под полосой на собственной панели. Щелкнув по одной из полос, можно скрыть или раскрыть соответствующее ей содержимое. На снимке три тега <multipanel> показывают свое содержимое, а три нет. Эти полосы перетаскивать нельзя.

    Тег <floatingview> - определенный автором приложения тег, даже еще более сложный, чем <multipanelset>. Он используется в отладчике JavaScript. У него также есть XBL-определение, специфичное только для данного приложения. Данное определение можно при необходимости скопировать и использовать повторно. Этот тег показан на рисунке 8.7.

    Содержимое <floatingview> в отладчике JavaScript

    Рис. 8.7.  Содержимое <floatingview> в отладчике JavaScript

    На этом снимке показан отладчик, отображающий четыре тега <floatingview>. Три размещены друг над другом слева (с двумя тегами <splitter>), а один занимает всю правую панель. Этот тег также состоит из строки заголовка (например, "Loaded Scripts") и определенного автором приложения содержимого на панели ниже. Пиктограмма в правом конце заголовка используется для скрытия всей панели <floatingview>. Пиктограмма в левом конце тоже скрывает панель, но создает новое маленькое окно, отображающее тот же самый тег <floatingview>. Строку заголовка <floatingview> также можно перетаскивать поверх другого тега <floatingview>, что позволяет менять положение тега.

    И <multipanelset>, и <floatingview> больше всего подходят для опытных пользователей и приложений для работы с объектами.

    8.2.7. Специализированные элементы управления

    В XUL есть несколько тегов, которые нельзя отнести к той или иной категории. Так как они некоторым образом относятся к навигации, мы рассмотрим их здесь.

    8.2.7.1. Тег <progressmeter>

    <progressmeter> - тег только для чтения с поддержкой специальных возможностей. Он предоставляет собой гистограмму, состоящую из одного столбца, которая отображает состояние какого-то процесса. Вы наблюдаете именно за тегом <progressmeter>, когда ждете загрузки web-страницы или большого файла. Вот специальные атрибуты <progressmeter>:

    mode value label
    

    mode определяет тип <progressmeter>. Если его значение - undetermined, тогда индикатор состояния представляет задачу или еще выполняющуюся, или уже завершенную. Этот индикатор по целям схож с сообщением "Подождите...". В темах Mozilla данный индикатор представлен анимированным изображением, похожим на палочку со спиральными полосами. Если значение mode - determined, тогда индикатор разделяется на две части. Одна из них оформляется так, чтобы соответствовать уже выполненной части задачи, а другая - оставшейся. Вместе получим 100% выполнения задачи. Атрибут value (и свойство) определяет, какая часть задачи уже завершена, в процентах. Атрибут label используется для поддержки специальных возможностей и не отображается на экране.

    <progressmeter> - не более чем два тега <spacer> со стилями, расположенными один за другим. В UNIX-версии индикатор состояния может быть немного некорректным, если указаны атрибуты mode="undetermined" и value одновременно, как показано на рисунке 8.3. Индикатор также может быть вертикальным, если задать соответствующее значение атрибуту orient, но это выглядит некрасиво, требует для корректировки дополнительных стилей и путает размещение на странице. Лучше этого избегать.

    Чтобы <progressmeter> был визуально больше, используйте атрибуты minheight и minwidth.

    8.2.7.2. Тег <colorpicker>

    Тег <colorpicker> - особенность Mozilla, появившаяся для компоновщика и вкладки "Внешний вид" диалога "Настройки". Он позволяет выбирать цвет CSS 2 из каталога цветов. Оба применения требуют дополнительных усилий программиста в дополнение к этому основному тегу, чтобы сделать его завершенным. У <colorpicker> нет удобной модульной реализации.

    Если вы хотите поэкспериментировать с этим тегом, тогда для начала стоит заметить, что свойство цвета DOM-объекта тега принимает определенное значение при нажатии на любую из отображаемых ячеек каталога. Все остальные функции смешаны с реализацией приложения, использующего этот тег. При желании можно исследовать XBL-определение colorpicker.xml.

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

    8.2.7.3. Не теги

    Хотя исходные тексты Mozilla подразумевают, что мог бы быть XUL-тег <fontpicker>, в версии 1.2.1 его не было.

    В chrome Mozilla есть XBL-определение тега <titlebar>. Он иногда встречается в других XBL-определениях, но у него нет статуса настоящего XUL-тега. Это не более чем <hbox>, содержащий <label> и <image>. Он предназначен для моделирования строки заголовка, добавляемой к окну менеджером окон графической среды. Диалог FilePicker - XUL-приложение, которое можно создать объектом, но не собственным тегом.

    На этом обзор самых очевидных XUL-тегов, относящихся к навигации, завершается.

    8.3. Альтернатива: таблицы стилей

    Элементы управления навигацией могут использовать несколько расширений стилей Mozilla.

    Расширение стиля -moz-appearance поддерживает темы графической среды для элементов управления. Некоторые его значения относятся к XUL-тегам, рассмотренным в этой главе:

    toolbox toolbar statusbar statusbarpanel progressbar
    progressbarvertical progresschunk progresschunk-vertical
    tab tab-left-edge tab-right-edge tabpanels tabpanel
    scrollbartrack-horizontal scrollbartrack-vertical
    

    Mozilla предоставляет свойство стиля overflow CSS 2 с некоторыми удобными альтернативами, как показано в таблице 8.1.

    Mozilla также поддерживает scrollbar: auto.

    Таблица 8.1. Расширения стиля overflow: scroll CSS 2

    Значение свойства overflowРазмещение содержимогоПоявление полос прокрутки
    scrollРазмещается внутри контейнера, прокручиваетсяПолосы прокрутки появляются всегда
    -moz-scrollbars-noneРазмещается внутри контейнера, прокручиваетсяПолосы прокрутки не появляются никогда
    -moz-scrollbars-noneРазмещается внутри контейнера, прокручиваетсяПоявляется горизонтальная полоса прокрутки
    -moz-scrollbars-verticalРазмещается внутри контейнера, прокручиваетсяПоявляется вертикальная полоса прокрутки

    8.4. Практика: панели инструментов и вкладки NoteTaker

    В этом разделе "Практика" мы добавим в наше приложение NoteTaker навигацию. Если бы у NoteTaker было собственное полноценное окно приложения, как у классического браузера, например, тогда строка основного меню и набор пиктограмм для панелей инструментов были бы очевидной точкой старта. Однако это расширение, и его навигация смешивается с навигацией по основному приложению. Мы можем только спроектировать его как набор элементов.

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

    Вот те части, которые составляют систему навигации NoteTaker:

    1. Диалог, над которым мы работали до текущего момента.
    2. Панель инструментов для управления заметками в окне основного приложения.
    3. Пункт меню "Инструменты" основного приложения.
    4. Маленькое встроенное окно, которое будет отображать заметку о содержимом данной web-страницы.

    Когда-нибудь в меню "Инструменты" может появиться и "Менеджер заметок", но уже не в этой книге. Маленькое встроенное окно требует особого подхода. Оно описывается в главе 10, "Окна и панели". Здесь мы обратимся к оставшимся задачам.

    Окно диалога требует всего лишь нескольких улучшений. Мы заменим неуклюжие <toolbarbutton>, <deck> и часть функции action() простым тегом <tabbox>. В листинге 8.6 показан этот новый код, очень легко читающийся.

    <tabbox id="dialog.tabs"> 
      <tabs> 
        <tab id="dialog.tab.edit" label="Edit" 
          accesskey="E" selected="true"/> 
        <tab id="dialog.tab.keywords" label="Keywords" accesskey="K"/> 
      </tabs> 
      <tabpanels> 
        <tabpanel> 
          ... Здесь идет содержимое панели ... 
        </tabpanel> 
        <tabpanel> 
          <description>Содержимое будет добавлено позже.</description> 
        </tabpanel> 
      </tabpanels> 
    </tabbox>
    
    Листинг 8.6. Элемент управления <tabbox> для диалога NoteTaker

    Результат этого изменения показан на рисунке 8.8.

    Диалог NoteTaker, реализованный с <tabbox>.

    Рис. 8.8.  Диалог NoteTaker, реализованный с <tabbox>.

    Мы также должны обновить функцию action(), так как отдельные вкладки по-прежнему можно выбирать одним нажатием клавиши. Нам нужно управлять <tabbox> из JavaScript. Заглянув в файл xul.css архива toolkit.jar в chrome, мы увидим, что для всех тегов имеются связки: <tabbox>, <tabs>, <tab> и <tabpanel>. Изучив файл tabbox.xml (в chrome), содержащий эти XBL-связки, мы обратим внимание, что у <tabbox> есть свойство selectedIndex, а у <tab> есть свойство selected. Опять же, эти имена соответствуют XML-атрибутам и стандарту DOM 2 HTML. Мы используем свойство <tabbox> selectedIndex. Необходимые изменения функции action() приведены в листинге 8.7.

    // старый код 
    var card = document.getElementById("dialog." + task); 
    var deck = card.parentNode; 
    if ( task == "edit" ) deck.selectedIndex = 0; 
    if ( task == "keywords") 
    deck.selectedIndex = 1; 
    // новый код 
    var tabs = document.getElementById("dialog.tabs"); 
    if ( task == "edit" ) tabs.selectedIndex = 0; 
    if ( task == "keywords") 
    tabs.selectedIndex = 1;
    
    Листинг 8.7. Новая смена вкладок с помощью <tab>.

    Очевидно, что <tabbox> и <deck> действуют похожим образом, но у <tabbox> более удачный графический интерфейс. На этом изменения в диалоге завершаются.

    Панель инструментов NoteTaker - XUL-тег <toolbar>, который появится в основном окне классического браузера. На ней будет кнопка "Edit", с помощью которой пользователи смогут попадать в основной диалог NoteTaker. На ней также будут элементы формы, с помощью которых можно быстро создавать и удалять заметки в NoteTaker. С панели управления можно будет создавать точно такую же заметку, как и через окно правки, только значения по умолчанию будут предоставлены практически для всех полей. Это удобная альтернатива вроде панели инструментов "Google bar", которая иногда используется, чтобы добавить поисковую машину в окно классического браузера. При отображении независимо от основного окна браузера панель инструментов NoteTaker выглядит так, как показано на рисунке 8.9.

    Создание заметки NoteTaker и панель навигации

    Рис. 8.9.  Создание заметки NoteTaker и панель навигации

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

    <?xml version="1.0"?> 
    <?xml-stylesheet href="chrome://global/skin/" 
     type="text/css"?> <!DOCTYPE window> 
    <window xmlns="http://www.mozilla.org/keymaster/
     gatekeeper/ there.is.only.xul"> 
      <toolbox> 
        <toolbar id="notetaker-toolbar"> 
          <description value="Note:"/> 
      <textbox/> 
          <description value="Keyword:"/> 
      <menulist editable="true"> 
        <menupopup> 
          <menuitem label="draft"/> 
          <menuitem label="reviewed"/> 
          <menuitem label="final"/> 
          <menuitem label="published"/> 
          <menuitem label="cool"/> 
        </menupopup> 
      </menulist> 
      <toolbarbutton label="Edit"/> 
      <toolbarbutton label="Delete"/> 
      <toolbarbutton label="Save"/> 
      </toolbar> 
      </toolbox> 
    </window>
    
    Листинг 8.8. Разметка панели инструментов NoteTaker

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

    Последнее изменение, которое нужно внести в код в этой главе - добавить пункт в меню "Инструменты" окна классического браузера, так что пользователи смогут открывать диалог правки, если панель инструментов не установлена. Для этого нужен только тег <menuitem>, который будет соответствовать изменениям панели инструментов позднее.

    8.5. Отладка: проблемы навигации

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

    В сущности, основной источник проблем с этими тегами навигации - дизайн. Если слишком далеко отойти от целей этих тегов, они не будут размещаться так, как надо. Лучше применять их так, как было задумано. Альтернатива - пристально изучать механизм размещения этих XUL-тегов и затем подкорректировать их поведение, добавив дополнительные стили.

    Еще одна проблема, с которой вы можете столкнуться, - сложности с фокусом на элементах управления и выделением. Хотя эта система была недавно усовершенствована, иногда можно нарушить работу окна, запущенного экземпляра платформы и даже графической среды Microsoft Windows, если XUL-код написан некорректно. Признаки этой проблемы - окно, у которого два или более курсоров в полях ввода (теги <textbox>), рассинхронизация текущего фокуса и текущего выделения. Чтобы узнать, вызывается ли это ошибками в реализации, нужно перезагрузить компьютер и проверить, не улучшилось ли отображение и "поведение" этой страницы.

    8.6. Итоги

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

    Mozilla предоставляет большое число вспомогательных элементов навигации на уровне пользовательского интерфейса. XUL-теги вроде и структурируют интерфейс, но ценой более сложной интерактивной среды. Тег - один из первых примеров мощного тега с собственным блочным объектом.

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

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

    Навигация дает пользователю свободу перемещаться по приложению. Такая свобода дополняется системой команд Mozilla, которая позволяет пользователю что-то делать после завершения перемещения. Эта система рассматривается в следующей главе.


    об авторе

    Администрация сайта не несет ответственности за содержание и соблюдение копирайта на материалы,
    найденные в свободном доступе на просторах интернета без указания авторских прав на них.
    Документация предоставляется, размещается и публикуется пользователями сайта с максимально известной информацией об источнике.
    Если Вы являетесь правообладателем представленных статей, и не хотите их здесь видеть - напишите нам, и мы с радостью их удалим с сайта





    Сайт создан в системе uCoz