Obx/Docu/ru/Twins.odc

Описание системы примерами: ObxTwins
(C) Перевод на русский язык: Чернышов Л.Н., 2005.

ObxTwins - пример отображения-контейнера (view). Контейнеры бывают в основном двух видов:
- динамические могут содержать произвольное и переменное число других отображений любого типа;
- статические содержат точно предопределенное число отображений, и, как правило, их типы и размещение предопределены и не могут быть изменены.

Наш пример показывает реализацию статического контейнера; для примера динамического контейнера смотрите, пожалуйста, подсистемуForm.

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

Двойное отображение прикрепляет свои внедренные отображения к двум контекстным объектам (расширения Models.Context). Таким образом, контекст содержит отображение, ее ограничивающую рамку и указатель на двойное отображение. Контекст является связью между контейнером и содержащеимся отображением; это позволяет содержащемуся отображению связываться с его контейнером. Для этой цели содержащееся отображение имеет указатель на свой контекст. Через этот указатель отображение может обратиться к его среде; например, чтобы спросить, каков его текущий размер, или спросить об изменении размера или другого свойства его контейнера.
Контекст буферизует рамку ограничения его картинки; близнец (одно из отображений) может изменить размещение содержащихся отображений, вызывая процедуру RecalcLayout, которая модифицирует два контекстных объекта некоторым походящим способом. В наиболее типичном примере, верхняя картинка для целей демонстрации могла бы иметь постоянную высоту, ObxTwins показывает более динамическое размещение, где ширины остаются постоянными, но высоты - 1/3 для верхнего отображения и 2/3 для нижнего.

Самая интересная часть этого примера - процедура HandleCtrlMsg. Она обрабатывает входящие сообщения тремя различными способами. Обычно она только переправляет сообщение к содержащемуся отображению, находящемуся в данный момент в фокусе. Сообщения, связанные с прокруткой (Controllers.PollSectionMsg, Controllers.ScrollMsg, Controllers.PageMsg), всегда отправляются нижнему отображению вне зависимости от текущего фокуса. И наконец, сообщения курсора (Controllers.CursorMessage) всегда отправляются картинке под курсором.
Двойное отображение может быть реализовано с собственной моделью или без нее. В этом примере используется пустая фиктивная модель. Она не содержит состояния, и она не сохраняется и не загружается. Её единственная цель состоит в том, чтобы позволить более гибкое поведение копирования. Отображение без модели реализует метод CopyFromSimpleView, который является всегда глубоким копированием. Картинка с моделью вместо этого реализует метод CopyFromModelView, который может использоваться для глубокого копирования, поверхностного копирования или копирования с новой моделью (Views.CopyWithNewModel). Обратите внимание, что, если Вы имеете приложение, где нет смысла иметь несколько окон, показывающих одно и то же двойное отображение, тогда вы можете полностью избавиться от модели.

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

ObxTwinssources

 "ObxTwins.Deposit; StdCmds.Open"