У цьому уроку ми переходимо до створення другого демо-додатку. Спочатку ми подивимось, як можна додати зображення і потім помістити його в контейнер з областю, що прокручується. (Scroller). У наступному уроку ми додамо трохи логіки і перетворимо наш додаток у міні-гру.
Зазвичай в нативній розробці, для відображення зображень на екрані Tizen використовує Image віджет. Він дозволяє показувати графічні елементи, а також відображати анімаційні .gif зображення і програвати їх.
Цей віджет дозволяє використовувати або файл із зображенням, або напряму область у пам’яті, в якій зберігається зображення. Останнє зручно, коли ви завантажуєте зображення з Інтернету, і у вас немає необхідності його зберігати. Базовий проект, який ми використовуємо в цьому уроку, можна завантажити тут.
Це звичайний UI-додаток для носимого пристрою, в якому створюється вікно і конформант.
Для початку створіть Image і зробіть його вмістом контейнера-конформанта, як показано на схемі нижче.
Візьміть наступне зображення і завантажте його в свій додаток.
Графічні, аудіо і інші ресурси додатку рекомендується поміщати в директорію res/ вашого проекту. Тільки ваш додаток має доступ до цієї папки, весь вміст якої, під час збірки додатку, потрапляє в .tpk пакет. Створіть всередині директорію images/ і помістіть в неї зображення.
Необхідно розширити структуру з віджетами вказівником для нового віджета, який буде створено далі. Як і всі віджети в EFL бібліотеці, вказівник на зображення буде мати тип Evas_Object.
Evas_Object *image;
Ви повинні отримати наступний вміст вашої структури з віджетами:
typedef struct _UIData {
Evas_Object *win;
Evas_Object *conform;
Evas_Object *image;
} UIData;
Створіть функцію, в якій буде реалізовано роботу з віджетом зображень.
static void
_image_create(UIData *ui)
{
}
Для створення нового віджета зображень, використовуйте наступну функцію:
ui->image = elm_image_add(ui->conform);
У функцію створення зображення передайте вказівник на віджет, який буде предком для зображення. У результаті метод поверне вказівник на новостворене зображення.
Тепер потрібно вказати шлях до зображення, яке буде відображатися у вашому віджеті. Для цього використовується наступна функція:
Eina_Bool elm_image_file_set(Evas_Object *obj, const char *file, const char *group);
Ця функція приймає в якості другого параметру повний шлях до файлу зображення на пристрої, цей шлях можливо отримати підчас виконання програми. У момент компіляції нам відомо лише шлях до зображення відносно кореня проекту чи каталогу res/ цього проекту. Тепер необхідно отримати абсолютний шлях під час виконання. У Tizen є функція для отримання повного шляху до деяких директорій додатку під час виконання. Відповідно, можна отримати шлях до директорії і склеїти його з шляхом до файлу директорії.
Наступна функція дозволяє отримати абсолютний шлях до директорії res/ додатку під час виконання програми.
char *app_get_resource_path();
Реалізуйте функцію, яка буде генерувати повний шлях з відносного.
static void
_file_abs_resource_path_get(char *res_file_path, char *abs_path, int buf_size)
{
char *res_dir_path = app_get_resource_path();
if (res_dir_path)
{
snprintf(abs_path, buf_size, "%s%s", res_dir_path, res_file_path);
free(res_dir_path);
}
}
Наступна функція першим параметром приймає відносний шлях до зображення, другим – вказівник на буфер, куди потрібно помістити абсолютний шлях, третім параметром – розмір буферу.
Тепер можна використовувати цю функцію. Після створення об’єкту віджета, додайте наступний код.
char abs_path_to_image[PATH_MAX] = {0,};
_file_abs_resource_path_get("images/image.jpg", abs_path_to_image, PATH_MAX);
Ви можете використовувати цю функцію завжди, коли буде необхідність отримати повний шлях до будь-якого вашого ресурсу додатку. Тепер завантажте зображення у ваш віджет.
elm_image_file_set(ui->image, abs_path_to_image, NULL);
Залишилось тільки відобразити віджет.
evas_object_show(ui->image);
Викличте вашу функцію для створення віджету зображення і помістіть його в конформант.
static void
_conformant_create(UIData *ui)
{
...
_image_create(ui);
elm_object_content_set(ui->conform, ui->image);
...
}
Запустіть ваш додаток і подивіться на результат.
Як було зазначено раніше, Image віджет підтримує відображення .gif анімації. За замовчанням якщо ви вкажете шлях до такої анімації, віджет відобразить файл, як статичне зображення, для старту анімації необхідно визвати декілька допоміжних функцій.
Спробуйте використати наступну анімацію в якості ресурсу.
Помістіть її за наступним шляхом: res/images/animation.gif.
Тепер вкажіть вашому віджету шлях до цієї анімації. Для цього замініть “images/image.jpg” на “images/animation.gif”
_file_abs_resource_path_get("images/animation.gif", abs_path_to_image, PATH_MAX);
Для віджету зображень є функція, яка перевіряє чи підтримує вказаний ресурс анімацію. ЇЇ необхідно викликати після того, як зображення було встановлено у віджет.
Eina_Bool is_animated = elm_image_animated_available_get(ui->image);
Оскільки за замовчанням віджет використовує будь-який ресурс, як статичне зображення, потрібно явно вказати йому, що за умови використання ресурсом анімації – вона має бути використана. Після цього можна запустити анімацію.
if (is_animated)
{
elm_image_animated_set(ui->image, EINA_TRUE);
elm_image_animated_play_set(ui->image, EINA_TRUE);
}
Крім того, у будь-який момент, ви можете зупинити анімацію, викликавши останню зі значенням другого параметру - EINA_FALSE.
Тож тепер, якщо вказане зображення буде підтримувати анімацію, то її програвання почнеться автоматично. Запустіть додаток і подивіться на результат.
У випадку, якщо у вас велика кількість контенту повинна бути розміщена на екрані, ви можете використовувати скроллер, який має область прокрутки.
Далі демо-додаток буде розширено скроллером, який потрібно додати, як прошарок між конформантом і зображенням. Таким чином, якщо розмір початкового зображення буде більшим ніж розмір дисплею, ви можете прокручувати зображення в областях, які не потрапили в межі дисплею. Тобто, скроллер буде поміщено в конформант, а зображення – в скроллер, як показано на схемі знизу.
Розширте вашу структуру з віджетами вказівником для нового контейнеру, який буде створено далі. Так як всі віджети в EFL бібліотеці, вказівник на скроллер буде мати тип Evas_Object.
Evas_Object *scroller;
Ви повинні отримати наступний вміст вашої структури з віджетами:
typedef struct _UIData {
Evas_Object *win;
Evas_Object *conform;
Evas_Object *scroller;
Evas_Object *image;
} UIData;
Додайте функцію, в якій буде реалізовано роботу зі скроллером.
static void
_scroller_create(UIData *ui)
{
}
Для створення нового скроллеру, використовуйте наступну функцію:
ui->scroller = elm_scroller_add(ui->conform);
У функцію для створення скроллера передайте вказівник на конформант, який буде предком для нього. У результаті метод поверне вказівник на новостворений скроллер.
Замість зображення, яке ви напряму вставляєте в конформант, помістіть туди скроллер.
static void
_conformant_create(UIData *ui)
{
...
_scroller_create(ui);
elm_object_content_set(ui->conform, ui->scroller);
...
}
Аби зберегти ієрархію віджетів, необхідно поміняти віджету зображень батька. У разі видалення скроллера, ваше зображення не з’явиться аби-де, а буде коректно видалено разом зі скроллером.
ui->image = elm_image_add(ui->scroller);
За замовчанням віджет Image відображує зображення, які відмасштабовані відповідно до розміру віджету, тобто якщо ви використовуєте зображення з розміром 720x360 у віджеті з розміром 360x360, то зображення буде відцентровано і відмасштабовано до розміру 360x180. Дивіться приклад на схемі знизу.
Вам необхідно зробити розмір Image віджету таким же, як і розмір початкового зображення. Спочатку візьміть об’єкт зображення нижнього рівня, який знаходиться на рівні Evas модуля. З нього ви далі зможете отримати розмір ресурсу. Не плутайте зображення (elm_image) з модулю Elementary і зображення Evas (evas_object_image), останнє зберігає більш детальну інформацію об’єкту, а перше – це смарт об’єкт, який має додаткові функції, наприклад для анімації чи для отримання сигналу, про те, що на віджеті відбулась подія «клік».
Evas_Object *evas_image = elm_image_object_get(ui->image);
Тепер отримайте розмір зображення, використавши наступну функцію:
int w = 0;
int h = 0;
evas_object_image_size_get(evas_image, &w, &h);
Останнім кроком, встановіть віджету зображення дані, отримані в якості мінімального і максимального розміру, таким чином, при завантаженні зображення, віджет буде приймати точно такий же розмір, що і файл.
evas_object_size_hint_min_set(ui->image, w, h);
evas_object_size_hint_max_set(ui->image, w, h);
Тепер додайте зображення, яке буде більше ніж розмір екрану годинника (в даному випадку екран: 360x360).
Помістіть дане зображення в res/images/image_big.png.
Тепер вкажіть віджету шлях до цього зображення. Для цього замініть “images/animation.gif” на “images/image_big.png”
_file_abs_resource_path_get("images/image_big.png", abs_path_to_image, PATH_MAX);
Тепер викличне функцію для відображення сроллера.
evas_object_show(ui->scroller);
Помістіть віджет зображень в скроллер.
elm_object_content_set(ui->scroller, ui->image);
Запустіть додаток і подивіться на результат.
Повний початковий код цього уроку ви можете завантажити тут WearLesson018.