Опубликовано: 25 Октября 2017
(Демо приложение №1)
Обработка событий в приложениях. Основные события кнопки

В этом уроке мы разберем каким образом обрабатываются события в Tizen. Рассмотрим какие существуют типы событий.

В конце мы добавим обработку события нажатия на кнопку, созданную в прошлом уроке.

Описание концепта событий в Tizen

Как уже говорилось разработка нативных приложений в Tizen основывается на библиотеках EFL. А в EFL все события обрабатываются при помощи связи сигналов с функциями обратного вызова.

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

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

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

Виды событий в EFL

В EFL существует 4 основных вида событий, рассмотрим их:

Ecore event – это события самого низкого уровня EFL приложения такие события приходят прямо от системы, их не советуется использовать.

Evas event – такие события привязаны к холсту на котором происходит прорисовка графического интерфейса, такие события являются тоже достаточно низко-уровневыми, и их тоже не советуется использовать, исключение если вы будете делать свою прорисовку.

Следующие типы событий мы рассмотрим подробнее, поскольку будем их часто использовать в дальнейшем в наших уроках.

Evas object event – эти события происходят для объектов находящихся на холсте, это могут быть примитивные объекты или полноценные виджеты.

Evas smart event – это события самого высокого уровня, относятся они к самим виджетам.

То что мы рассмотрели касается к событиям графического интерфейса, на подобии событий изменения размера или отображения некоторых графических элементов.

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

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

События типа Evas object event

События такого типа происходят для всех графических объектов размещенных на холсте, будь то прямоугольник, или кнопка. Вы можете отлавливать события одним и тем же образом для разных объектов.

Ниже представлен список наиболее часто используемых событий.

Следующие 3 события относятся к нажатию в области объектов одним пальцем.

EVAS_CALLBACK_MOUSE_DOWN - начало нажатия в области объекта.

EVAS_CALLBACK_MOUSE_UP - конец нажатия.

EVAS_CALLBACK_MOUSE_MOVE - точка указателя переместилась относительно предыдущей позиции.

Важно:

Событие перемещения указателя EVAS_CALLBACK_MOUSE_MOVE может быть вызвано раньше чем EVAS_CALLBACK_MOUSE_DOWN даже если вы нажимаете пальцем на экран. А также может быть вызвано без события нажатия если к устройству подключена компьютерная мышь.

Следующие 3 события относятся к касаниям объектов, вторым или более по-счету пальцем одновременно

EVAS_CALLBACK_MULTI_DOWN - новый палец прикоснулся в области объекта.

EVAS_CALLBACK_MULTI_UP - один из пальцев закончил касание

EVAS_CALLBACK_MULTI_MOVE - один из пальцев закончил касание

EVAS_CALLBACK_FREE - вызывается перед очисткой памяти выделенной для графического объекта.

Следующие события срабатывают после вызовов некоторых функций системой или из наших программ

EVAS_CALLBACK_SHOW - cрабатывает после вызова функции evas_object_show().

Важно:

Событие срабатывает именно после вызова функции evas_object_show(), а не после того как объект отобразился на экране.

EVAS_CALLBACK_HIDE - cрабатывает после вызова функции evas_object_hide().

EVAS_CALLBACK_MOVE - cрабатывает после вызова функции evas_object_move().

EVAS_CALLBACK_RESIZE - cрабатывает после вызова функции evas_object_resize().

EVAS_CALLBACK_DEL - cрабатывает после вызова функции evas_object_del().

Давайте рассмотрим как же использовать такие события.

Допустим у нас есть графический объект размещенный на холсте

Evas_Object *rect;

Зарегистрируем обработчик на событие удаления объекта следующим образом.

evas_object_event_callback_add(rect, EVAS_CALLBACK_DEL, del_callback, user_data);

И реализуем саму функцию обработчик del_callback которая должна вызваться при вызове удаления нашего объекта.

static void
del_callback(void *user_data, Evas *evas, Evas_Object *obj, void *event_info)
{
   // Тело обработчика
}

Для всех событий типа Evas object event сигнатура обработчика одинаковая. Так первым параметром приходит указатель на пользовательские данные которые мы передаем при регистрации обработчика последним аргументом, второй параметр – объект холста на котором произошло событие, он не часто используется. Третьим параметром является объект над которым произошло событие, или вызов функции которая привела к событию, и последним параметром приходит указатель на структуру описывающую событие в деталях.

Последний параметр не всегда валидный, иногда параметр – NULL. Но например при событии нажатия туда приходит объект структуры из которой можно получить например координаты в которых произошло нажатие, это иногда бывает полезно. Мы будем описывать подробнее последний параметр при использовании в других уроках.

События типа Evas smart event

Умные события (evas smart event) имеют место только для полноценных виджетов библиотеки Elementary.

У каждого виджета имеется свой уникальный список поддерживаемых событий. Так например у кнопки одним из доступных событий является "отжатие".

В дальнейшем в уроках к конкретным виджетам мы будем описывать какие события доступны для них.

Для регистрации таких событий используется следующая функция.

evas_object_smart_callback_add(widget, "event", event_callback, user_data);

Обработчик умного события должен иметь следующую сигнатуру.

void smart_callback(void *user_data, Evas_Object *obj, void *event_info);

Первым параметром приходит указатель на пользовательские данные, вторым – объект для которого сработало событие, а третьим – дополнительная информация о событии, но последний параметр может быть и пустым.

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

К примеру вы создадите индикатор заряда батареи и хотите что бы при использовании вашего виджета можно было отлавливать событие когда значение заряда изменилось. Так для эмуляции события, назовем его "charge,value,changed", необходимо будет в нужный момент вызвать следующую функцию.

evas_object_smart_callback_call(battery_widget, "charge,value,changed", event_info);

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

Таким образом вы сможете создавать свои умные виджеты, и переиспользовать их.

Добавляем обработку события в демо-приложение

Для виджета-кнопки доступны следующие умные события.

"clicked" – событие клика, происходит при быстром прикосновении и отжимании в области кнопки.

"pressed" – событие зажатия кнопки.

"unpressed" – событие отжатия кнопки.

"repeated" – настраиваемое событие, может неоднократно вызываться в случае зажатия кнопки. Для этого события возможно настроить начальную задержку перед срабатыванием, а также интервал между повторениями.

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

Для начала зарегистрируем события.

static void
_button_create(Evas_Object *parent)
{
   ...

   evas_object_smart_callback_add(ui->button, "pressed", press_cb, NULL);
   evas_object_smart_callback_add(ui->button, "unpressed", unpress_cb, NULL);
   evas_object_smart_callback_add(ui->button, "repeated", repeat_cb, NULL);
   evas_object_smart_callback_add(ui->button, "clicked", click_cb, NULL);
}

Теперь реализуем сами обработчики в которых будем выводить в лог информацию о событии.

Для использования логгирования сначала включим следующий заголовочный файл.

#include <dlog.h>

И реализуем обработчики

static void
press_cb(void *data, Evas_Object *button, void *event_info)
{
   dlog_print(DLOG_DEBUG, "lesson15", "Событие PRESS!");
}

static void
unpress_cb(void *data, Evas_Object *button, void *event_info)
{
   dlog_print(DLOG_DEBUG, "lesson15", "Событие UNPRESS!");
}

static void
repeat_cb(void *data, Evas_Object *button, void *event_info)
{
   dlog_print(DLOG_DEBUG, "lesson15", "Событие REPEAT!");
}

static void
click_cb(void *data, Evas_Object *button, void *event_info)
{
   dlog_print(DLOG_DEBUG, "lesson15", "Событие CLICK!");
}

Как было сказано ранее, виджет поддерживает событие "repeated", но для его использования необходима активация у кнопки должен быть включен режим аutorepeat.

Для включения вызовите следующую функцию и передайте в нее вторым параметро EINA_TRUE для включения режима или EINA_FALSE для отключения.

elm_button_autorepeat_set(ui->button, EINA_TRUE);

Сейчас если кнопка будет зажата то событие "repeated" будет вызываться непрерывно (каждую итерацию главного цикла приложения), это поведение режима автоповторения по умолчанию. Существуют дополнительные функции для настройки интервалов (начального и промежуточного).

Зададим начальный интервал срабатывания 2 секунды, а промежуточный полсекунды. Для этого вызовем две следующие функции:

elm_button_autorepeat_initial_timeout_set(ui->button, 3);
elm_button_autorepeat_gap_timeout_set(ui->button, 0.5);

Давайте запустим наше приложение.

Как видно все наши события кнопки обрабатываются, время срабатывания события "repeated" можно оценить в окне логгирования, а также можно сделать вывод что событие клик это совокупность события нажатия и отпускания кнопки, как и должно быть.

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

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *