О custom control’ах и их реализации в виде gadget’ов

О custom control’ах и их реализации в виде gadget’ов

28.10.2002

Автор: Ронин Виктор
Источник: ladoshki.com

Изначально в PalmOS вложено порядка 10 различных видов элементов управления, это:

  • Button (push, graphic, repeat и некоторые их комбинации)
  • Field
  • Table
  • Scollbar
  • два вида slider (обычный и feedback)
  • Bitmap
  • Checbox (которые можно организовывать в группы, для получения функциональности аналогичной radiobutton в Windows)
  • Graffiti shift indicator
  • List
  • Selector trigger
  • а также некоторое кол-во стандартных диалогов…

По мнению многих разработчиков под PalmOS данный выбор элементов
управления не слишком логичный, так как функционирование большинства
кнопок и selector trigger’а очень схожи, и не имело смысла их разделять
на разные элементы управления. Также отсутствует разумная система связи
scrollbar’ов с field’ами и tabl’ами. При этом не хватает таких
элементов управления, как дерево или поле ввода с отображение * вместо
букв (для ввода паролей) и д. р.

Так или иначе, для разработчиков было оставлено несколько методов
расширения набора элементов управления : полная обработка всех событий
и прорисовка специальных элементов управления (custom control)
на экране или использование gadget’ов. Рассмотрение использования
gadget’ов значительно интересней и информативней, так как
оно предполагает облегчение создания новых элементов управления.

Как описано в PalmOS документации : Gadget позволяет
вам реализовывать новые UI объекты. Gadget содержит базовую информацию,
которая полезна для реализации функций прорисовки gadget’а и обработки
пользовательского ввода. Фактически есть два типа gadget’ов — обычные
(для PalmOS версии младше 3,5) и extended (для PalmOS версии 3,5
и старше).

Про простые gadget’ы хватит сказать буквально пару слов — они могут
выставляться в constructor’е и являются ни чем большим как просто
прямоугольником, координатами которого вы можете воспользоваться
при написании своего кода. Вам необходимо будет вставить свой код на
обработку событий frmOpenEvent и frmUpdateEvent для прорисовки
gadget’а, и на penDownEvent и keyDownEvent вызывать функции, которые
будут проверять, не произошло ли действие (щелчок или ввод буквы)
именно в gadget’е. И в случае, если событие произошло произошло,
то выполнять какие-то действия. Как результат — обычные gadget’ы
отличаются от метода полной обработки и прорисовки, только тем, что в
constructor’е можно будет видеть позицию gadget’а и его координаты
будут храниться не в коде, а в ресурсах.

Extended gadget’ы предоставляют гораздо больше возможностей.
Функцией FrmSetGadgetHandler можно выставить обработчик событий
происходящих в вашем gadget’е. Система автоматически будет посылать
событий прорисовки/стирания, удаления и щелчков обработчику вашего
gadget’а.

Важное замечеание: При установки SDK 5,0, изменилось описание обработчика событий gadget’а с

Boolean (FormGadgetHandlerType) (struct FormGadgetType *gadgetP, UInt16 cmd, void *paramP), на

Boolean (FormGadgetHandlerType) (struct FormGadgetTypeInCallback *gadgetP, UInt16 cmd, void *paramP)

На самом деле, если поглядеть в.h файлы, то можно увидеть,
что FormGadgetType и FormGadgetTypeInCallback полностью идентичны.
Эти изменения в PalmOS 5,0 были вызваны тем, что в нем запрещен прямой
доступ к атрибутам control’ов из программы. Поэтому им пришлось
разделить доступ к атрибутам gadget’а из самой программы (который надо
запрещать), и доступ к атрибутам gadget’а из обработчика (который надо
разрешать).

Итак вернемся к Extended Gadget. В обработчик gadget’а передается
4 типа событий — formGadgetDrawCmd (необходимо прорисовать gadget),
formGadgetEraseCmd (необходимо стереть gadget), formGadgetDeleteCmd
(вызывается при удаление формы) и formGadgetHandleEventCmd (может
содержать или frmGadgetEnterEvent — при щелчке в области gadget’а, либо
frmGadgetMiscEvent, в случае если мы посылаем «user defined» событие
gadget’у). Более детально об этом можно почитать в Palm OS Programmer
API References, в статье о FormGadgetHandler.

Также достаточно удобной возможность является возможность передачи
обработчику Gadget’а указателя на данные, для этого можно
воспользоваться функцией FrmSetGadgetData. Обычно эта функция
вызывается на frmOpenEvent. Если вы воспользовались этой функцией,
то перед закрытием формы, необходимо вызывать снова эту функцию,
но передав ей в виде параметра NULL, либо, это надо сделать внутри
обработчика gadget’а, на formGadgetDeleteCmd. Данная особенность
не описана в документации PalmOS, однако если функция не будет вызвана
перед закрытие с параметром NULL, то на некоторых реализациях PalmOS
закрытие формы вызовет ошибку.

Как я уже сказал, выше, не все продумано в Palm OS. Как показала
практика, всю необходимую функциональность не получается поместить
в обработчике gadget’а. Код обработки взаимодействия с scrollbar’ом,
прихода событий нажатий на кнопки или написания букв приходится
располагать в обработчике формы. При этом либо весь код пишется
в обработчике формы, либо в него помещается только код перенаправляющий
события в обработчик gadget’а, с помощью функции EvtAddEventToQueue.

Примеры реализации полноценных Gadget’ов вы можете посмотреть в DateBook из examples из SDK

Таким образом достаточно сложный вопрос использовать или нет
gadget’ы… Тут каждый должен выбрать для себя, либо он пишет все сам,
либо использует некую смесь из событий, обрабатываемых системой
и событий обрабатываемых самописаным кодом

Существует также еще три метода создания custom control’ов,
основанные на изменение прорисовки List’ов и Table’ов, а также
на изменении функционирования стандартных control’ов с помощью
перехвата функций.