У цьому уроку ми розберемо, яким чином в Tizen обробляються події і які типи подій існують. У кінці ми покажемо, як додати обробку події натискання на кнопку, яка була створена в минулому уроку.
Як уже говорилось раніше, розробка нативних додатків в Tizen ґрунтується на бібліотеках EFL. А в EFL всі події обробляються за допомогою зв’язку сигналів з функціями зворотного виклику.
У головному циклі додатку, на системному рівні, відбувається перевірка деяких параметрів, і у випадку, наприклад, події натискання на кнопку, система викликає зареєстровану функцію зворотного виклику для цієї події, якщо така функція-обробник була встановлена. Виклик обробника, як і його робота, відбувається у головному потоці додатку, тому необхідно максимально скорочувати функціонал таких обробників. Припустимо, що після натискання на кнопку у вашому додатку, ви повинні відправляти запит на сервер, у такому разі, поки запит не буде виконано, ваш інтерфейс користувача буде заблоковано. Тому, краще буде викликати запит у окремому потоці, для цього існує модуль Ecore_Thread передбачений для створення і керування потоками. У подальшому ми розберемо роботу з цим модулем в окремому уроку. На даному етапі достатньо пам’ятати, що в додатках, робота, яка навантажує процесор, повинна відбуватись у паралельних потоках, а не в обробниках подій.
У системі можуть відбуватись різноманітні події, наприклад зміна мови інтерфейсу на пристрої. Для того, аби після такої події мати можливість проводить будь-яку дію, необхідно викликом потрібної функції зареєструвати обробник на дану подію. Крім того, необхідно реалізувати саму функцію-обробник, при цьому сигнатура функції повинна бути відповідною.
В EFL існує 4 основні види подій:
Ecore event – в EFL додатку, це подія самого низького рівня, яка приходить прямо від системи. Тому їх не рекомендовано використовувати.
Evas event – такі події прив’язані до полотна, на якому відбувається промальовування графічного інтерфейсу. Вони є достатньо низькорівневими і їх не рекомендується використовувати, за виключенням випадків, коли ви будете робити своє промальовування.
Оскільки наступні типи подій будуть часто використовуватись у наших уроках, їх ми розглянемо більш детально.
Evas object event – ці події відбуваються для об’єктів, що знаходяться на полотні. Це можуть бути як примітивні об’єкти, так і повноцінні віджети.
Evas smart event – це події самого високого рівня, що відносяться до самих віджетів.
Все викладене вище стосується подій графічного інтерфейсу, таких як зміна розміру чи відображення графічних елементів.
Події і функції зворотного виклику також використовуютьсяу модулях, що відповідають за відмінну від графіки функціональність. Для кожного модуля існують свої типи подій, обробники яких виглядають по-різному. Наприклад, при необхідності отримати координати пристрою, ви не можете викликати функцію і одразу отримати їх. Спочатку пристрій має підготувати апаратну частину, потім отримати стійкі сигнали від супутників, обрахувати де знаходиться пристрій відносно супутників, і тільки після цього координати можуть бути отримані. Такі дії можуть займати деякий час, інколи навіть більше хвилини. У такому разі процес буде наступний: ви викликаєте функцію отримання координат, передаєте функцію зворотного виклику, яка виконується після всіх процедур обрахування і вже тоді зможете опрацювати отримані координати.
Події такого типу відбуваються для всіх графічних об’єктів, розміщених на полотні, чи то прямокутник, чи кнопка. Ви можете відловлювати події одним і тим же чином для різних об’єктів. Нижче представлено список подій, що використовуються найчастіше.
Наступні три події відносяться до подій натискання на область об’єктів одним пальцем.
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 – спрацьовує після виклику функції evas_object_show().
Важливо:
Подія спрацьовує після виклику функції evas_object_show(), а не після того, як об’єкт буде відображено на екрані.
EVAS_CALLBACK_HIDE – спрацьовує після виклику функції evas_object_hide().
EVAS_CALLBACK_MOVE - спрацьовує після виклику функції evas_object_move().
EVAS_CALLBACK_RESIZE - спрацьовує після виклику функції evas_object_resize().
EVAS_CALLBACK_DEL - спрацьовує після виклику функції evas_object_del().
Давайте розглянемо, як же використовувати такі події. Припустимо, що є графічний об’єкт, який розміщений на полотні:
Evas_Object *rect;
Необхідно зареєструвати обробник на подію видалення об’єкту наступним чином:
evas_object_event_callback_add(rect, EVAS_CALLBACK_DEL, del_callback, user_data);
І реалізувати саму функцію-обробник del_callback, яка повинна викликатись при видаленні об’єкту.
static voiddel_callback(void *user_data, Evas *evas, Evas_Object *obj, void *event_info)
{
// Тіло обробника
}
Для всіх подій типу Evas object event сигнатура обробника однакова. Першим параметром приходить вказівник на дані користувача, які ми передаємо останнім аргументом під час реєстрації обробника. Другий параметр – об’єкт полотна, на якому відбулась подія (не часто використовується). Третій параметр – об’єкт над яким відбулась подія чи виклик функції, яка призвела до події. Останнім параметром приходить вказівник на структуру, що описує подію в деталях. Розглянемо корисний приклад, коли при події натискання, туди приходить об’єкт структури, з якої можна отримати, наприклад, координати, в яких відбулось натискання. Останній параметр не завжди валідний, інколи параметр, що передається - це NULL. В інший уроках ми будемо більш детально описувати використання останнього параметру.
Розумні події (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" – подія відтискання кнопки.
"repeat" – може багаторазово викликатися під час затискання кнопки. Для цієї події можливо налаштувати ппочаткову затримку перез спрацюванням, а також інтервал між повтореннями події.
Тепер знаючи майже все про події інтерфейсу користувача, давайте розглянемо, як додати обробку цих подій кнопки в нашому додатку.
Спочатку, потрібно зареєструвати подію.
static void
_button_create(Evas_Object *parent)
{
...
evas_object_smart_callback_add(button, "pressed", press_cb, NULL);
evas_object_smart_callback_add(button, "unpressed", unpress_cb, NULL);
evas_object_smart_callback_add(button, "repeat", repeat_cb, NULL);
evas_object_smart_callback_add(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!");
}
Запустіть ваш додаток.
Як ви можете бачити, всі події кнопки обробляються. Можна зробити висновок, що подія-клік – це поєднання події натискання і відтискання кнопки, як і має бути.
У наступному уроку ми розглянемо текстовий віджет, в якому будемо змінювати текст після натискання на кнопку. Повний код уроку доступний тут WearLesson015