Починаємо створювати 5-й демо-додаток. У ньому ми навчимо вас як створювати циферблат, в якому можна буде змінювати стиль, а також передбачена можливість, за допомогою спеціального модуля, зберігати в системі інформацію про налаштування цього циферблату. У даному уроку ми розглянемо додаток-циферблат, візьмемо стандартний шаблон і підготуємо для нашого демо-додатку, прибравши з нього непотрібні елементи.
До цього моменту ми розказували як створювати UI додатки, у ваших демо, в цьому ж уроку ми покажемо як створювати додаток-циферблат. З назви можна припустити, що додаток повинен слугувати індикатором часу. Але це не обмежує функціонал циферблату. Він може бути використаний як повноцінний додаток з цікавими додатковими функціями: чи то відображення карти в якості фону, чи якийсь інший, не властивий циферблату, функціонал.
На перший погляд може здатись, що існують якісь серйозні відмінності між UI додатком і додатком-циферблатом, але насправді це не так.
Додаток-циферблат створюється таким же чином, як і звичайні додатки з інтерфейсом користувача. Невеликі відмінності існують при створенні базового вікна для циферблата, оскільки воно знаходиться в спеціальному місці, в графічній оболонці годинника, в усьому ж іншому, можна сказати, що це звичайний додаток. Тут ви так само можете використовувати все ті ж віджети, сервіси і датчики (GPS, датчик освітлення та інші), викликати вібрацію пристрою, посилати сповіщення та інше.
У додатку циферблат є обмеження на використання безелю і кнопки Назад. У наступних уроках, коли ми перейдемо до більш складних тем, ми розкажемо як обійти цю заборону за допомогою додаткового вікна.
Життєвий цикл циферблата передбачає спеціальну подію Time Tick, яка спрацьовує кожну секунду. Таким чином, в обробнику цієї події ми повинні виконати оновлення графічного інтерфейсу у відповідності з поточним часом (оновити числа або змінити кути стрілок, якщо циферблат має аналоговий стиль).
У Tizen студії є шаблон додатку-циферблата.
Давайте подивимось, як його можна створити.
Відкрийте File → New → Tizen Project.
Далі виберіть Template і натисніть Next >.
Виберіть профіль Wearable, версію платформи 2.3.2 і натисніть Next>.
Виберіть Native Application і натисніть Next>.
Далі виберіть шаблон циферблату Watch і натисніть Next>.
Останній крок: введіть ім’я проекту та ім’я пакету, з яким буде збиратись циферблат і натисніть Finish.
На відміну від UI додатків, які ви вже створювали у попередніх уроках, додаток-циферблат не запускається одразу після встановлення на пристрій чи емулятор. На емуляторах з версією 2.3.2 і нижче циферблати встановлюються в додатку налаштувань через меню циферблатів, як показано на відео.
На реальних годинниках потрібно затиснути на екрані з циферблатом, після того відобразиться вікно вибору циферблата, де ви зможете встановити свій, нижче продемонстровано як це можна зробити.
Як вже говорилось раніше, деякі шаблони мають зайві елементи. Тому аби зробити код більш зрозумілим, ми покажемо як його можна максимально спростити, викинувши всі непотрібні елементи.
Ми вже видалили з проекту заголовний файл, а файли, які необхідні для увімкнення, перенесли до файлу реалізації. Також було видалено конформант і зайві порожні обробники подій, оскільки вони не потрібні для цього демо.
#include <watch_app.h>
#include <Elementary.h>
#include <watch_app_efl.h>
typedef struct _UIData
{
Evas_Object *win;
Evas_Object *label;
} UIData;
static void
_ui_update(UIData *ui, watch_time_h watch_time)
{
const int BUF_SIZE = 256;
char text[BUF_SIZE] = {0,};
int hour24 = 0;
int minute = 0;
int second = 0;
watch_time_get_hour24(watch_time, &hour24);
watch_time_get_minute(watch_time, &minute);
watch_time_get_second(watch_time, &second);
snprintf(text,
BUF_SIZE,
"<font font_size=80><align=center>%02d:%02d:%02d</align></font>",
hour24,
minute,
second);
elm_object_text_set(ui->label, text);
}
static void
_watch_update(UIData *ui, watch_time_h watch_time)
{
if (watch_time == NULL)
{
watch_time_get_current_time(&watch_time);
_ui_update(ui, watch_time);
watch_time_delete(watch_time);
}
else
_ui_update(ui, watch_time);
}
static void
_label_create(UIData *ui, int width, int height)
{
ui->label = elm_label_add(ui->win);
const int label_heigh = 80;
evas_object_resize(ui->label, width, label_heigh);
evas_object_move(ui->label, 0, height / 2 - label_heigh / 2);
evas_object_show(ui->label);
}
static void
_window_create(UIData *ui, int width, int height)
{
watch_app_get_elm_win(&ui->win);
evas_object_resize(ui->win, width, height);
_label_create(ui, width, height);
evas_object_show(ui->win);
}
static bool
_app_create(int width, int height, void *data)
{
UIData *ui = data;
_window_create(ui, width, height);
_watch_update(ui, NULL);
return true;
}
static void
_app_terminate(void *data)
{
UIData *ui = data;
evas_object_del(ui->win);
}
static void
_app_time_tick(watch_time_h watch_time, void *data)
{
UIData *ui = data;
_watch_update(ui, watch_time);
}
int
main(int argc, char *argv[])
{
UIData ui = {0,};
watch_app_lifecycle_callback_s lifecycle_callbacks = {0,};
lifecycle_callbacks.create = _app_create;
lifecycle_callbacks.terminate = _app_terminate;
lifecycle_callbacks.time_tick = _app_time_tick;
return watch_app_main(argc, argv, &lifecycle_callbacks, &ui);
}
Тож, тепер ви бачите перед собою 8 невеликих функцій, давайте розглянемо, що робить кожна з них. Як і в будь-якій програмі на даній платформі, все починається з функції main().
int
main(int argc, char *argv[])
{
UIData ui = {0,};
watch_app_lifecycle_callback_s lifecycle_callbacks = {0,};
lifecycle_callbacks.create = _app_create;
lifecycle_callbacks.terminate = _app_terminate;
lifecycle_callbacks.time_tick = _app_time_tick;
return watch_app_main(argc, argv, &lifecycle_callbacks, &ui);
}
В main() створюється об’єкт структури з елементами інтерфейсу. Проініціалізуйте обробник деяких подій життєвого циклу циферблату, а саме: створення, подія зміни часу і закінчення. І в кінці запустіть головний цикл додатку-циферблату з допомогою виклику watch_app_main().
В обробнику _app_terminate() видаліть вікно. Воно є кореневим віджетом, тому це вікно подбає про видалення всієї ієрархії віджетів, які будуть створюватись.
static void
_app_terminate(void *data)
{
UIData *ui = data;
evas_object_del(ui->win);
}
В обробнику _app_create() створіть ваше кореневе вікно і всі віджети циферблату. Після цього викличте оновлення циферблату відповідно до поточного часу. Як вже було сказано раніше, створення вікна циферблату відрізняється від створення вікна в UI додатках. Тут вам необхідно викликати функцію watch_app_get_elm_win() замість elm_win_util_standard_add() . І в неї передати вказівник на об’єкт Evas, в який необхідно зберегти створене вікно.
Також у даному додатку аргументи обробника відрізняються від аргументів звичайного UI додатку: у функцію приходять ширина і висота області, в яку буде поміщено циферблат. Тобто, тут явно задається розмір вікну після його створення у відповідності до переданих аргументів.
static void
_window_create(UIData *ui, int width, int height)
{
watch_app_get_elm_win(&ui->win);
evas_object_resize(ui->win, width, height);
_label_create(ui, width, height);
evas_object_show(ui->win);
}
static bool
_app_create(int width, int height, void *data)
{
UIData *ui = data;
_window_create(ui, width, height);
watch_time_h watch_time = NULL;
watch_time_get_current_time(&watch_time);
_watch_update(ui, watch_time);
watch_time_delete(watch_time);
return true;
}
Нижче представлена функція, в якій створюється текстовий віджет для відображення часу.
static void
_label_create(UIData *ui, int width, int height)
{
ui->label = elm_label_add(ui->win);
const int label_heigh = 80;
evas_object_resize(ui->label, width, label_heigh);
evas_object_move(ui->label, 0, height / 2 - label_heigh / 2);
evas_object_show(ui->label);
}
У цьому демо-додатку не будуть використані контейнери для розмітки, а геометрія буде явно задана віджетам. Це виправдано, оскільки цей інтерфейс простий і буде складатись з віджета фону і текстового віджету.
Текстовому віджету буде встановлена висота в 80 пікселів і він буде розміщений посередині екрану (відносно його висоти і ширини).
Після створення віджетів, буде викликана створена вами функція оновлення циферблату, в якій викликається оновлення інтерфейсу з переданим чи поточним часом. У функції оновлення інтерфейсу, у відповідності до переданого туди об’єкту часу, повинен змінюватись текстовий віджет. Текстовий рядок формується з вказанням деяких параметрів стилю, для збільшення розміру тексту і відцентрування його по горизонталі. Детально про стилі текстових віджетів ми розповідали в уроку16.
static void
_ui_update(UIData *ui, watch_time_h watch_time)
{
const int BUF_SIZE = 256;
char text[BUF_SIZE] = {0,};
int hour24 = 0;
int minute = 0;
int second = 0;
watch_time_get_hour24(watch_time, &hour24);
watch_time_get_minute(watch_time, &minute);
watch_time_get_second(watch_time, &second);
snprintf(text,
BUF_SIZE,
" <font font_size=80> <align=center>%02d:%02d:%02d </align> </font>",
hour24,
minute,
second);
elm_object_text_set(ui->label, text);
}
static void
_watch_update(UIData *ui, watch_time_h watch_time)
{
if (watch_time == NULL)
{
watch_time_get_current_time(&watch_time);
_ui_update(ui, watch_time);
watch_time_delete(watch_time);
}
else
_ui_update(ui, watch_time);
}
Зверніть увагу, що для роботи з часом використовується спеціальний об’єкт типу watch_time_h, для роботи з ним передбачений зручний інтерфейс, хоча вам ніхто не забороняє працювати з struct tm із "time.h" .
Остання функція _app_time_tick() є обробником події зміни часу, вона викликається кожну секунду. Таким чином, у ній можна повертати стрілки чи змінювати цифри, що відображають час. Використайте функцію оновлення циферблату, що була створена вище.
static void
_app_time_tick(watch_time_h watch_time, void *data)
{
UIData *ui = data;
_watch_update(ui, watch_time);
}
У цей обробник першим параметром приходить інформація про поточний час системи, передайте її в функцію оновлення циферблату. Встановіть і запустіть ваш додаток і подивіться на результат.
Повний код прикладу ви можете скачати тут WearLesson028.
У подальшому ми розглянемо як реалізувати інші циферблати в якості демо-додатків і нам може не знадобитись текстовий віджет, тому ми його видалили і підготували порожній шаблон для демо-додатків циферблатів, його можна завантажити тут WearWatchTemplate. Також ви можете його використовувати для створення власних циферблатів замість стандартного шаблону середовища розробки.