Руководство программиста в Photon (1037671), страница 4
Текст из файла (страница 4)
Ресурсы виджетов используются для конфигурирования того, как они выглядят на экране, и их поведения. Вы можете редактировать ресурсы в PhAB, и после создания виджета Вы можете изменить многие из них вызовами функций PtSetResource( ) или PtSetResources( ). Ресурсы широко используются для управления данными, отображаемыми виджетом и задания того, как их отображать.
Например:
ресурс Pt_ARG_TEXT_STRING виджета PtLabel является строкой, выводимой на экран;
ресурсы виджета PtButton определяют, отображает ли кнопка строку и/или картинку (image), её текст, картинку, цвет, и что происходит, когда пользователь выбирает кнопку.
Важным типом ресурса, предоставляемого виджетами, является список ответных реакций (callback list), являющийся списком функций, запускаемых виджетом в ответ на определённые значимые пользовательские события. Например, виджет текстовой области вызывает соответствующие функции из своего списка ответных реакций всякий раз, когда пользователь вводит новое значение и нажимает Enter. При разработке приложения Вы можете добавить реакции в список ответных реакций виджета, задавая соответствующие действия в ответ на пользовательские события.
Жизненный цикл виджета
Виджет имеет присущий ему жизненный цикл, как показано ниже.
Рис. 3. Жизненный цикл виджета
Когда виджет оказывается востребованным, он создаётся или инициализируется (instantiated). После его создания появляется возможность манипулировать его атрибутами, или над ним можно производить действие.
Когда виджет создан, он не становится немедленно видим в пользовательском интерфейсе. Он должен быть реализован (realized). Если Вы используете PhAВ, Ваши виджеты реализуются автоматически; если Вы PhAВ не используете, Вы должны реализовать их, используя функцию PtRealizeWidget( ).
Реализация виджета автоматически реализует всех его потомков. Photon гарантирует, что потомки виджета реализуются перед ним самим, так что виджет может вычислить размер своей инициализации, основываясь на размерах своих детей. Вы можете задать, чтобы приложение уведомлялось, что виджет реализован, путём регистрирования ответной реакции в списке реакций Pt_CB_REALIZED. С помощью функции PtUnrealizeWidget( ) Вы можете временно скрыть виджет от пользовательского интерфейса, дереализовав его. Что касается реализации, Вы можете уведомить приложение, используя ресурс ответной реакции Pt_CB_UNREALIZED.
Когда виджет оказывается больше не нужным, Вы можете убить его. Вы можете уничтожить виджет, вызвав функцию PtDestroyWidget( ). В действительности виджет не уничтожается немедленно – он маркируется как подлежащий удалению в соответствующее время и добавляется в список виджетов, подлежащих уничтожению. Эти виджеты обычно уничтожаются внутри главной петли приложения после того, как отработают все ответные реакции, привязанные к событию.
Ваше приложение может определить ответные реакции Pt_CB_DESTROYED для любого виджета. Эти ответные реакции вызываются, когда виджет маркируется, как подлежащий уничтожению. Вы можете задать, чтобы приложение уведомлялось, когда виджет в действительности уничтожен, регистрацией функции со списком ответной реакции на уничтожение (Pt_CB_IS_DESTROYED) для виджета. Это особенно полезно для очистки структур данных, связанных с виджетом.
Геометрия виджета
Вы можете рассматривать виджет, как картинку или, подмонтированную фотографию. Виджет закрепляется на раме, называемой рамкой (by a frame, called a border – велик и могуч английский язык. Прим. пер.). Для виджета рамка – это набор контуров и создающие эффект выпуклости фаски, которые могут быть нарисованы вокруг внешних сторон.
Часть виджета, используемая для рисования, называется канвой (canvas). Для PtWidget – это область внутри рамки виджета. Для PtBasic и его потомков канва – это область внутри рамки виджета и границ. Другие виджеты, такие как PtLabel, определяют другие границы. Границы, формирующие затемнение (matt) и затеняющие любую часть канвы, распространяются за пределы отсечённой части. Эта затенённая область иногда называется как отсечённая (clipping) область (см. диаграмму на рис. 4).
Для наглядности на диаграмме канва и границы показаны различным цветом. В реальном виджете они одного цвета.
Рис. 4. Анатомия виджета PtBasic
Для виджета рамка является необязательной. Она рисуется, только если виджет подсвечен (т.е. в его ресурсе Pt_ARG_FLAGS установлен флаг Pt_HIGHLIGHTED). Рамка состоит из различных необязательных компонентов, в зависимости от установок в ресурсе Pt_ARG_BASIG_FLAGS.
Компонентами, рассматривая их от самых наружных вовнутрь, являются:
-
однопиксельная линия "гравировки";
-
однопиксельная наружная контурная линия;
-
фаска, ширина которой установлена в Pt_ARG_BEVEL_WIDTH;
-
однопиксельная внутренняя контурная линия.
Виджет имеет несколько важных атрибутов, определяющих геометрию этих элементов. Размеры виджета, Pt_ARG_DIM – это общий размер виджета, включая его границы.
Рис. 5. Позиция и размеры виджета
Pt_ARG_MARGIN_WIDTH определяет ширину границы слева и справа от канвы, и Pt_ARG_MARGIN_HEIGHT определяет высоту границы над и под канвой. Эти ресурсы определены в PtBasic. Другие классы виджетов определяют свои собственные ресурсы границ, которые могут быть добавлены к ширине и высоте базовой границы. Например, виджет надписи (label widget) обеспечивает различные границы для левой, правой, верхней и нижней сторон виджета. Они добавляются к базовым ширине и высоте для определения объёма пространства, оставляемого на каждую сторону канвы. Начальной точкой виджета (в целях выполнения любой прорисовки или позициониования любого порождаемого виджета) является верхний левый угол канвы. Все координаты, определяемые для виджета, являются относительными этого начала, как координаты всех событий, получаемых виджетом. Например, если виджет является контейнером, позиции всех его "детей" являются относительными этой точки.
Рис. 6. Начальная точка виджета и позиция его "ребёнка"
Для позиционирования "детей" контейнеры описаны только внешним краем рамки виджета. Позиция виджета содержится в ресурсе Pt_ARG_POS. Эта позиция является точкой в верхнем левом углу внешнего контура рамки виджета. Контейнер позиционирует своих детей выравниванием по этому ресурсу.
Доступ и модификация позиции и размеров виджета могут быть достигнуты одновременно использованием ресурса Pt_ARG_AREA, предоставляемого виджетом. Пространство виджета – это прямоугольник, определяемый позицией виджета и его размерами. Обычно оно не может быть вычислено до того, как виджет не будет реализован; Вы можете принудить виджет вычислить своё пространство вызовом PtExtentWidget( ); чтобы вынудить виджет и все его порождения вычислить свои пространства, необходимо вызвать PtExtentWidgetFamily( ). Как только пространство вычислено, Вы можете узнать его, получив данные ресурса Pt_ARG_EXTENT, или вызовом PtWidgetExtent( ).
Парадигма (система понятий) программирования
Давайте сравним, как Вы пишете не-PhAB (Photon) приложения текстового режима, и приложения PhAB.
Приложение текстового режима
Когда Вы пишете не-Photon'ное (текстового режима) приложение, Вы в основном концентрируетесь на основной программе, из которой Вы делаете такие вещи, как:
-
инициализация приложения
-
установка обработчиков сигналов
-
посылка и получение сообщений
-
итерации
-
вызов подпрограмм, если требуется
-
связь с консолью
-
и, наконец, выход.
Основная программа
Рис. 7. Структура приложения текстового режима
Не-PhAB приложение
Приложение Photon'а, написанное без PhAB, похоже на приложение текстового режима, за исключением того, что вы также:
-
инициализируете и реализуете виджеты приложения;
-
устанавливаете ресурсы виджетов, включая такие:
-
размер и позиция
-
привязка
-
текст
-
список ответных реакций
-
прочая
-
пишете подпрограммы ответных реакций для обработки событий виджетов. При этом Вам может понадобится:
-
создать окна и их виджеты, установить ресурсы, и затем реализовать их
-
создать меню из виджета PtMenuButton, установить ресурсы и ответные реакции, реализовать эти меню
-
уничтожить виджеты
-
прочая
-
вызвать PtMainLoop( ) в Вашей основной программе для обработки событий.
Обычно одна из Ваших ответных реакций выполняет завершение приложения. Написание приложений без PhAB означает, что Вы будете работать непосредственно с виджетами – со всей их кучей.
Рис. 8. Структура приложения Photon, написанная без использования PhAB
PhAB приложение
Когда Вы разрабатываете PhAB приложение, main-программа Вам предоставляется. Вместо того, чтобы заботиться об основной программе, Вы:
-
обеспечиваете функцию, которая инициализирует приложение;
-
устанавливаете обработчики сигналов, которые обрабатывают сигналы, когда те прибывают, и вызываете написанные Вами функции работы с сигналами;
-
устанавливаете функции ввода для сообщений;
-
пишете ответные функции для обработки событий от виджетов.
Основная программа всегда закольцована, обрабатывая события, когда они случаются. Обычно одна из Ваших ответных функций завершает приложение. PhAB обрабатывает для Вас массу деталей – Вы концентрируетесь на функциональности Вашего приложения, а не на виджетах.
Рис. 9. Структура приложения Photon'а, написанная PhAB
Дополнительно, Вы не имеете в Вашем коде размер и позиции виджетов; Вы делаете это визуально в PhAB. PhAB также просматривается после инициализации, реализации, дереализации и уничтожения Ваших виджетов. PhAB даже обеспечивает модулем меню, что делает простым создание меню. Вы можете видеть, почему мы рекомендуем использовать PhAB!
Библиотеки Photon'а
Интерфейс программирования приложений Photon'а (API) – организован как набор функций, каждая из которых характеризуется двухсимвольным префиксом:
Al функции перевода PhAB (PhAB Translation functions), позволяющие Вам работать с файлами перевода (tranlation files) (для приложений PhAB или баз данных сообщений) без использования редактора перевода. Эти подпрограммы отсутствуют в библиотеке совместного доступа, чтобы их использовать, необходимо линковать приложение с библиотекой phexlib;
Ap функции PhAB, работающие с модулями, базами данных виджетов, переводом (translation) и прочая. Эти подпрограммы отсутствуют в библиотеке совместного доступа, чтобы их использовать, необходимо линковать приложение с библиотекой Ap;
mbstr функции строк многобайтных символов. См. приложение "Поддержка многоязычности Unicode";
Pd функции работы с рисуемым контекстом;
Pf службы шрифтов, включая метрики текстов, и генерация побитых карт символьных строк (generation of bitmaps of character strings). Для более полной информации см. главу "Шрифты";
Pg низкоуровневые графические функции, позволяющие получить доступ к богатому набору примитивов в графических драйверах. Эти функции используются в библиотеках виджетов и могут также быть вызваны непосредственно, используя виджет PtRaw. См. главу "Необработанное рисование и мультипликация";
Ph примитивы Photon'а, являющиеся совокупностью запросов на рисование и отправляющие их в микроядро Photon'а для управления и отсечения до тех пор, пока они не достигнут графического драйвера, готовые к отображению на экран. Поскольку эти функции не являются общеиспользуемыми при программировании приложений, их тяжело использовать в библиотеках графики и виджетов;