Главная » Просмотр файлов » Руководство программиста в Photon

Руководство программиста в Photon (953920), страница 60

Файл №953920 Руководство программиста в Photon (Руководство программиста в Photon) 60 страницаРуководство программиста в Photon (953920) страница 602013-09-22СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 60)

Имеются две функции, которые Вы можете использовать для получения системной информации:

PhQuerySystemInfo() Получение информации о данном регионе

PtQuerySystemInfo() Получение информации о виджете (обычно окно)

PhQuerySystemInfo() отсылает сообщение серверу каждый раз, когда Вы её вызываете.

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

Обе функции – и PtQuerySystemInfo(), и PhQuerySystemInfo() – заполняют структуру типа PhSysInfo_t, которую выделяет в памяти Ваше приложение. Более полная информация – в "Справочнике библиотечных функций Photon'а".

Особый интерес представляет одна область – графическая полоса пропускания в gfx.bandwidth. Это значение может быть использовано для модификации поведения интерфейса, основанного на скорости связи. Например, простое изменение состояния может заменить изощрённую мультипликацию, если полоса пропускания равна Ph_BAUD_SLOW или ниже. Также хорошей идеей является выполнение проверки того, может ли совместно используемая память применяться для рисования; флаг Ph_GCAP_SHMEM в gfx.capabilities установлен, если все графические драйверы поддерживают функции семейства ...mx() и все они запущены на Вашем узле.

Глава 23. События

Взаимодействия между приложениями, пользователями и сервером Photon'а представлено через структуры данных, называемых событиями. В этой главе обсуждается:

  • События мыши ["Pointer events" – в общем случае, конечно, не мыши, а курсора манипулятора. Но для лучшего понимания пишу – мышь. Ибо как иначе перевести "press the pointer button"??? – Прим. пер.]

  • Генерация события

  • Координаты события

  • Обработчики события – необработанные и отфильтрованные ответные реакции

  • Накопление событий

  • Сжатие событий

  • Перетаскивание

Информация по событию хранится в структуре типа PhEvent_t; см. "Справочник библиотечных функций Photon'а".

События мыши

Чаще всего при обработке того, что пользователь делает, когда указывает на виджет, Вы будете использовать ответные реакции этого виджета.

Нажатие кнопки

Когда Вы нажимаете на кнопку мыши, Photon генерирует событие Ph_EV_BUT_PRESS для виджета, имеющего в этот момент фокус.

Отпускание кнопки

Когда Вы отпускаете нажатую кнопку, Photon генерирует два события Ph_EV_BUT_RELEASE:

  • Одно событие подтипа Ph_EV_RELEASE_REAL

  • Одно – подтипа Ph_EV_RELEASE_PHANTOM

Когда Вы отпускаете кнопку мыши, реальное отпускание попадает на указатель мыши; фантомное отпускание всегда проходит на тот же регион (и позицию), который получил нажатие кнопки.

Другими словами, если Ваш виджет увидел нажатие, он также увидит и фантомное отпускание. И в зависимости от того, где был указатель мыши, вы можете получить, а можете и не получить реальное отпускание. Если Ваш виджет получил и реальное и фантомное отпускание, реальное всегда приходит первым.

Несколько щелчков

Нажимаете ли Вы или отпускаете кнопку мыши, событие включает в себя счётчик щелчков. Как Ваше приложение определяет, что Вы щёлкнули, а не выполнили двойной щелчок?

В данных по событию имеется счётчик щелчков, связанный с событиями Ph_EV_BUT_PRESS и Ph_EV_BUT_RELEASE; чтобы получить эти данные, вызовите функцию PhGetData(). Данными для этих событий являются структуры типа PhPointerEvent_t (см. подробнее в "Справочнике библиотечных функций Photon'а"); её член click_count даёт количество Ваших щелчков кнопкой мыши.

Если Вы продолжаете щёлкать достаточно быстро, не двигая мышь, счётчик продолжает возрастать. Если Вы перемещаете мышь или на время прекращаете щёлкать мышью, счётчик сбрасывается и Photon генерирует событие

Ph_EV_BUT_RELEASE с подтипом Ph_EV_RELEASE_ENDCLICK.

Иными словами, первый щелчок генерирует событие Ph_EV_BUT_PRESS и пару событий Ph_EV_BUT_RELEASE (одно реальное REAL и одно фантомное PHANTOM) со счётчиком click_count, установленным в 1. Затем, в зависимости от того, щёлкнул ли пользователь достаточно быстро вновь или нет, Вы получите либо

  • событие Ph_EV_BUT_PRESS и пару событий Ph_EV_BUT_RELEASE со счётчиком click_count, установленным в 2;

либо

  • событие Ph_EV_BUT_RELEASE с подтипом Ph_EV_RELEASE_ENDCLICK.

После второго щелчка Вы либо получаете третий, либо ENDCLICK, и так далее. Но в конечном счёте Вы получаете ENDCLICK – и в следующий раз, когда пользователь щёлкнет, счётчик щелчков вновь равен 1.

Клавиши-модификаторы

Если Вам надо определить, какие клавиши были в событии мыши, вызовите функцию PhGetData(), чтобы получить данные по событию, которые включают события Ph_EV_BUT_PRESS и Ph_EV_BUT_RELEASE. Данными для этих событий является структура типа PhPointerEvent_t (описанная в "Справочнике библиотечных функций Photon'а"); проверьте её член key_mods, чтобы определить клавиши-модификаторы, которые были нажаты.

Например, эта ответная реакция Pt_CB_ACTIVATE предоставляет список клавиш-модификаторов, которые были нажаты, когда была отпущена кнопка мыши:

/* Стандартные хеадеры */

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

/* Инструментальные хеадеры */

#include <Ph.h>

#include <Pt.h>

#include <Ap.h>

/* Локальные хеадеры */

#include "abimport.h"

#include "proto.h"

int check_keys( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo ) {

PhPointerEvent_t *event_data;

/* предотвращает предупреждения (варнинги) об отсутствии ссылок */

widget = widget, apinfo = apinfo, cbinfo = cbinfo;

if (cbinfo->event->type != Ph_EV_BUT_RELEASE) {

printf ("Это не событие Ph_EV_BUT_RELEASE\n");

}

else {

printf ("Это событие Ph_EV_BUT_RELEASE\n");

event_data = (PhPointerEvent_t *) PhGetData (cbinfo->event);

if (event_data->key_mods & Pk_KM_Shift ) printf (" Shift\n");

if (event_data->key_mods & Pk_KM_Ctrl ) printf (" Ctrl\n");

if (event_data->key_mods & Pk_KM_Alt ) printf (" Alt\n");

}

return( Pt_CONTINUE );

}

Генерирование событий

В этом разделе описывается использование функции PhEmit(), а также

  • нацеливание на определённые регионы

  • нацеливание на определённые виджеты

  • события, генерируемые клавиатурными клавишами

Основным способом генерирования событий в Вашем приложении является вызов функции PhEmit():

int PhEmit(PhEvent_t *event,

PhRect_t *rects,

void *data);

Её аргументами являются:

event

Указатель на структуру PhEvent_t. Приложение, генерирующее событие, должно установить следующие члены:

  • type – тип события.

  • subtype – подтип события (если необходимо).

  • flags – модификаторы события (напр., направление).

  • emitter – структура типа PhEventRegion_t; Вам необходимо установить по меньшей мере идентификатор региона, генерирующего событие.

  • translation – при генерировании события обычно устанавливается в (0,0).

  • num_rects – количество прямоугольников в аргументе rects функции. Если Вы устанавливаете значение num_rects в 0, Вы также должны передать в качестве rects NULL.

  • event–>collector.rid – если Вы устанавливаете идентификатор накопителя в 0, событие ставится в очередь для каждого должным образом чувствительного региона, интересующегося событием.

Если вы устанавливаете идентификатор накопителя равным идентификатору какого-то региона, только этот регион замечает событие.

Менеджер Photon'а, после того, как поставил копию события в очередь к приложению, устанавливает в структуре события следующие члены:

  • timestamp – время, когда событие было сгенерировано (в миллисекундах);

  • collector – структура типа PhEventRegion_t, которая включает идентификатор региона-накопителя.

rects

Массив структур PhRect_t (см. "Справочник библиотечных функций Photon'а"), указывающих на набор начальных прямоугольников события. Если этот аргумент является NULL'ом, набор состоит из единственного прямоугольника, соответствующего генерирующему региону.

data

Данные, действительные для того типа события, которое было сгенерировано. Каждый тип событий имеет свой собственный тип данных, как описано в описании структуры PhEvent_t в "Справочнике библиотечных функций Photon'а".

Если специфические для события данные не находятся в примыкающей области памяти, функция PhEmitmx() может Вам показаться более полезной, нежели PhEvent():

int PhEmit(PhEvent_t *event,

PhRect_t *rects,

int mxparts,

struct_mxfer_entry *mx);

Кодами возврата функций PhEmit() и PhEmitmx() являются:

Неотрицательное значение

Успешное завершение

-1

Произошла ошибка; значение ошибки установлено в errno

Нацеливание на определённые регионы

Иногда приложению необходимо нацелить событие непосредственно на определённый регион, без совершения путешествия события через всё пространство событий, до прибытия на этот регион. Вы можете использовать неисключительное событие (inclusive event) или направленное событие (direct event), чтобы обеспечить обнаружение события конкретными регионами.

Неисключительное событие

Для неисключительного события выполните следующее:

  • Установите идентификатор генерирующего региона (т.е. event–>emitter.rid) равным значению идентификатора целевого региона – это приведёт к тому, что событие будет сгенерировано автоматически из этого региона.

  • установите флаг Ph_EVENT_INCLUSIVE в члене flags события – в результате менеджер Photon'а сгенерирует это событие в генерирующий регион перед тем, как запускать его в пространство событий.

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

Направленное событие

Для направленного события выполните следующее:

  • Установите идентификатор генерирующего региона (т.е. event–>emitter.rid) равным значению идентификатора региона Вашего приложения.

  • Установите идентификатор региона-накопителя (т.е. event–>collector.rid) равным значению идентификатора целевого региона.

  • Установите флаг Ph_EVENT_DIRECT в члене flag события – это приведёт к тому. что менеджер Photon'а сгенерирует событие непосредственно из генерирующего региона в регион-накопитель.

Нацеливание на определённые виджеты

Если Вы хотите послать событие на определённый виджет, Вы можете вызвать функцию PhEmit(), как это описано выше, но Вам необходимо отследить массу мелочей, в том числе убедиться, что

  • событие доставлено в надлежащее окно

  • виджет ещё имеет фокус – перед Вашим событиемв очередь могли поступить и другие события.

Проще вызвать функцию PtSendEventToWidget(). Эта функция отдаёт событие заданному виджету напрямую и без задержки. Это действует значительно более определённо и эффективно, чем в случае применения функции PhEmit(). Прототип этой функции такой:

int PtSendEventToWidget(PtWidget_t *widget,

PhEvent_t *event);

События, генерируемые клавиатурными клавишами

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

  • Генерировать событие Ph_EVENT_KEY из региона устройств:

event–>emitter.rid = Ph_DEV_RID;

Набор прямоугольников должен состоять из одного пикселя – если Вы не используете менеджер окон, или, если Photon'овский менеджер окон установлен на использование фокуса курсора, позиция этого пикселя определит, какое окно откликнется на событие.

  • Если Вы знаете регион, которому Вы хотите отослать событие, сгенерируйте событие Ph_EV_KEY непосредственно на этот регион:

event –>collector.rid = rid;

Характеристики

Тип файла
Документ
Размер
7,62 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
Почему делать на заказ в разы дороже, чем купить готовую учебную работу на СтудИзбе? Наши учебные работы продаются каждый год, тогда как большинство заказов выполняются с нуля. Найдите подходящий учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6367
Авторов
на СтудИзбе
309
Средний доход
с одного платного файла
Обучение Подробнее