17.3. Группы Турбо Паскаль В.В. Фаронов

Замечательным свойством видимых элементов Turbo Vision является их способность образовывать группы. Все группы являются потомками абстрактного объекта TGroup. Любая программа в конечном счете наследуется от TProgram или TApplication и, следовательно, является потомком TGroup, т.е. представляет собой группу.
Группа - это просто пустое окно. Главная особенность группы заключается в том, что она может управлять входящими в нее элементами. Как и любой другой видимый элемент, группа должна уметь заполнять нужным изображением выделенную ей часть экрана и обрабатывать все связанные с этой областью события. Однако в большинстве случаев группа обращается за выполнением требуемых действий к своим элементам. Например, визуализация группы происходит исключительно с помощью методов Draw тех элементов, которые образуют группу. С другой стороны, некоторые команды могут относиться к группе в целом. Например, группе может адресоваться команда cmClose (закрыть), в результате которой будет уничтожено изображение группы, т.е. очищен выделенный ей участок экрана. Для реализации этой команды группа будет последовательно передавать ее всем входящим в нее элементам.
Важно помнить, что группа обладает способностью включать в себя видимые подэлементы динамически, в ходе исполнения программы. Как правило, состав группы определяется действиями пользователя: если, например, он нажал командную клавишу, связанную с раскрытием опции главного меню, группа TDesktop, ответственная за рабочую зону экрана, обогащается дополнительными видимыми подэлементами «выпавшего» меню. После нажатия клавиши Esc эти элементы будут удалены из состава группы.
17.3.1. Создание группы и изменение ее состава
Создание группы осуществляется за счет создания экземпляра объекта-наследника TGroup и присоединения к нему всех видимых элементов группы. Любой видимый объект, т.е. наследник TView, имеет два поля: Owner и Next. Поле Owner указывает на владельца этого элемента, а поле Next - на следующий равный ему подэлемент группы. При включении видимого элемента в группу его поля изменяются так, что Owner содержит ссылку на экземпляр группы-владельца, a Next имеет значение NIL. После добавления к группе еще одного элемента поле Next ранее включенного элемента изменяет свое значение и содержит ссылку на этот новый элемент. Таким образом создается связанный список подэлементов группы (рис. 17.4).
Для присоединения элемента должны использоваться методы Insert или ExecView. Метод Insert присоединяет очередной видимый элемент к списку подэлементов группы. В зависимости от набора связанных с подэлементом признаков этот элемент может размещаться в центре (признаки ofCenterX и/или ofCenterY), стать активным (ofSelectable) и, наконец, появиться на экране (sfVisible). После создания подэлемента управление передается следующему за обращением к Insert оператору программы.
Метод ExecView осуществляет те же действия, что и метод Insert, однако после создания видимого подэлемента управление будет передано в него и оператор, следующий за обращением к ExecView, получит управление только после уничтожения этого подэлемента. Более точно процесс взаимодействия с программой элемента, присоединенного к группе методом ExecView, можно описать следующим образом. Любой видимый элемент наследует виртуальный метод Valid, с помощью которого он может сигнализировать своему владельцу о том, насколько успешно он выполнил возложенные на него обязанности. Обычно Valid возвращает True, если успешно создан и размещен в динамической памяти экземпляр объекта, и False,- в противном случае. Объект может перекрыть метод Valid и возвратить False, если он хочет оставить управление у себя,- именно так, например, поступает объект TDialog. Метод ExecView приостанавливает исполнение следующего оператора программы до тех пор, пока все подэлементы группы не вернут Valid = True. Таким образом, метод ExecView используется в том случае, когда среди подэлементов группы есть хотя бы один элемент, реализующий диалог с пользователем.
Метод Delete удаляет подэлемент группы из связанного списка.
Image
Puc. 17.4. Связанный список элементов группы
17.3.2. Z-упорядочение и дерево видимых элементов
Последовательное присоединение подэлементов к группе приводит к так называемому Z-упорядочению видимых элементов. Z-упорядочение - это трехмерная модель видимых элементов, в которой координаты X и Y определяют положение элементов на экране, а координата Z - порядковый номер элемента в группе. Например, на рис. 17.5 показана Z-модель элементов окна с рамкой и скроллером.
В этой модели каждый элемент можно представить в виде стеклянной пластины, накладывающейся на уже существующее изображение. То изображение, которое мы видим на экране, есть проекция трехмерной модели на плоскость XY. Трехмерный образ позволяет «взглянуть» на видимые элементы со стороны и увидеть порядок, в котором они присоединяются к группе.
Важно помнить, что любая группа визуализирует свои подэлементы в порядке, определяемом их Z-упорядочением. Для рис. 17.5 это означает, что сначала создается изображение рамки, очерчивающей все окно, затем на рамку накладываются полосы скроллера, потом - сам скроллер с текстом, а накрывает сверху все изображение и скрепляет его в единое целое прозрачная пластина TWindow.
Для того чтобы группа нашла связанный с ней список подэлементов, используется поле First, входящее в любой видимый объект. Это поле содержит NIL, если данный элемент - терминальный видимый объект; если этот элемент - группа, поле First содержит указатель на первый вставленный в группу подэлемент, т.е. на самый «нижний» элемент в смысле Z-упорядочения. Таким образом, цепочка ссылок First - Next образует дерево видимых элементов, так как каждый элемент Next может быть новой группой и в этом случае его поле First <> NIL.
Image
Рис.17.5. Z-модель видимых элементов окна
Программа Turbo Vision всегда владеет строкой меню, строкой статуса и рабочей зоной экрана, а следовательно, имеет дерево видимых элементов, показанное на рис. 17.6.
Image
Рис. 17.6. Основное дерево видимых элементов TApplication
Отметим, что деревья видимых элементов показывают принадлежность элементов, а не их иерархию в генеалогии объектов Turbo Vision, т.е. связи на рис. 17.6 определяют функциональную подчиненность экземпляров объектов Application, MenuBar, Desktop и StatusLine.
Деревья видимых элементов динамически изменяются в ходе работы программы. Они могут расти, если к программе присоединяются новые группы, или уменьшаться, если эти группы уничтожаются. В отличие от этого генеалогическое дерево объектов может только расти за счет создания потомков.
Все ветви дерева видимых элементов всегда заканчиваются терминальными видимыми объектами.
17.3.3. Активные элементы
Внутри любой группы видимых элементов в каждый момент времени может быть выбран (активизирован) один и только один элемент. Даже если в программе открыто несколько окон с текстом, активным считается только то окно, с которым Вы работаете в данный момент. Более того, поскольку окно представляет собой группу, в нем будет активным лишь один элемент. Если, например, Вы воздействуете мышью на полосу скроллера, будет активна именно эта полоса. Рис. 17.7 иллюстрирует сказанное: на нем показано дерево видимых элементов для двух открытых окон, причем активные элементы выделены двойной рамкой.
Image
Puc. 17.7. Цепочка активности видимых элементов просмотра текста
Цепочка активности видимых элементов используется при обработке событий (см. гл.18).
Активный элемент обычно выделяется на экране тем или иным способом. Например, выбранное окно очерчивается двойной рамкой, а остальные - одинарной; внутри диалогового окна активный элемент выделяется яркостью (цветом). С помощью метода Select видимый элемент можно сделать активным по умолчанию в момент его создания. При активизации группы активизируется ее подэлемент, указанный как активный по умолчанию. Пользователю может потребоваться изменить текущий активный видимый элемент. Он может это сделать, манипулируя мышью, или нажав командную клавишу (если элемент связан с командной клавишей), или, наконец, с помощью клавиши Tab.
Заметим, что существуют видимые элементы, которые нельзя сделать активными. Например, не может быть активным видимый элемент TBackground (фон рабочей зоны экрана). В момент создания элемента с помощью признака ofSelectable Вы можете указать, будет ли этот элемент выбираемым, т.е. можно ли его сделать активным в ходе работы программы. Однако, если Вы объявите выбираемым тот же элемент TBackground, он все равно не сможет активизироваться, так как знает, что на самом деле активизация ему недоступна. Точно также на сможет активизироваться рамка окна (заметим, что указать на рамку мышью можно, и программа может, например, перемещать окно с рамкой, однако это еще не означает активизации рамки: рамка не может быть объектом диалога с пользователем). Обычно сброс признака ofSelectable используется для того, чтобы запретить элементу стать активным, он, в принципе, может активизироваться, но его активизация в программе не нужна. Таким способом можно, например, сделать неактивной метку в диалоговом окне и, следовательно, превратить ее в статический поясняющий текст.