У цьому уроку мова піде про спеціальний bg віджет, який використовується як графічний елемент для фону.
Як вже було сказано, віджет використовується у якості фону додатку. Насправді, це не означає, що ви обов’язково повинні використовувати його, натомість можна використати віджет-зображення. Але якщо вам потрібен статичний фон - ми рекомендуємо саме bg.
Превага віджета фону – це те, що ви можете задавати йому як зображення, так суцільний колір. Таким чином, на відміну від віджета зображення, віджету фону можна встановити колір за допомогою спеціально створеного для цього інтерфейсу.
Особливістю віджету фону є здатність задавати режим відображення. Це може бути розтягування по всій області, чи у випадку якщо розмір зображення менший за розмір віджету – заміщення всього простору.
Тепер необхідно додати фон у ваш циферблат, який ви створили у попередньому уроку. Як і зазвичай, додайте поле для вашого нового віджету у структуру.
typedef struct _UIData
{
Evas_Object *win;
Evas_Object *bg;
Evas_Object *label;
} UIData;
Напишіть функцію для створення віджету фону і помістіть її виклик до створення текстового віджету, оскільки вам необхідно відобразити спочатку фон, а потім цифри, що відображають час, в іншому випадку цифри будуть сховані за фоном.
static void
_bg_create(UIData *ui, int width, int height)
{
}
static void
_window_create(UIData *ui, int width, int height)
{
...
_bg_create(ui, width, height);
_label_create(ui, width, height);
...
}
Для створення самого об’єкту віджету, зробіть наступний виклик:
ui->bg = elm_bg_add(ui->win);
Як було сказано раніше, в цьому демо-додатку не буде використано контейнери для розміщення компонентів, тому потрібно явно задавати розміри компоненту, використовуючи передані у функцію аргументи. Потім потрібно відобразити віджет.
evas_object_resize(ui->bg, width, height);
evas_object_show(ui->bg);
Встановіть темно-зелений колір вашому фону. Для цього викличте функцію:
elm_bg_color_set(ui->bg, 0, 80, 20);
Встановіть і запустіть ваш циферблат і подивіться на результат.
У вас має вийти циферблат з зеленим фоном і сірими числами, що відображають час.
Додайте різноманітність у ваш циферблат, дозволивши змінювати стиль натисканням на цифри. Для цього вам потрібно визначити стилі або як буде виглядати ваш циферблат, реалізувати функції встановлення для фону потрібного кольору або зображення, додати у форматований рядок (де ви задаєте текст часу) колір тексту і створити обробник натискання на цифри.
Спочатку визначте, що в стиль буде входити наступне:
- тип стилю, тобто в якості фону буде використовуватись зображення чи суцільний колір;
- для більшої зручності, колір тексту заданий HTML кодом кольору;
- три компоненти RGB для задання кольору фону (функція приймає саме три параметри для трьох каналів кольорів, а не HTML код);
- ім’я файлу зображення для фону у разі використання не кольорового стилю циферблату. Визначивши, що вам потрібно, опишіть структуру даних в коді:
typedef struct _Style
{
Eina_Bool is_image;
char *digits_color;
int bg_r;
int bg_g;
int bg_b;
char *image_name;
} Style;
Визначте набір стилів, які ви надаєте користувачу:
1. Жовті числа (#edf8bd), темно-червоний фон (104,0,32).
2. Світло-фіолетові числа (#9598bc), гірчичний фон (117, 104, 0).
3. Світло-червоні числа (#eec4c7) і темно-бірюзовий фон (8,60,55).
4.Темно-бірюзові числа (#00332e) і зелений фон (71,188,53).
5.Темно-бірюзові числа (#005848) і фонове зображення, як на картинці нижче.
6. Білі числа (#ffffff) і наступне фонове зображення.
Тепер додайте зображення у ваш проект у папку res/ і визначте стилі коду, щоб їх можна було виправити.
static Style styles[] = {
{EINA_FALSE, "edf8bd", 104, 0, 32},
{EINA_FALSE, "9598bc", 117, 104, 0},
{EINA_FALSE, "eec4c7", 8, 60, 55},
{EINA_FALSE, "00332e", 71, 188, 53},
{EINA_TRUE, "005848", 0, 0, 0, "bg1.png"},
{EINA_TRUE, "ffffff", 0, 0, 0, "bg2.png"},
};
У вашу структуру з графічними компонентами додайте поле, в якому ви будете зберігати індекс поточного стилю.
typedef struct _UIData
{
Evas_Object *win;
Evas_Object *bg;
Evas_Object *label;
int style_index;
} UIData;
Додайте зміни стилю чисел у відповідності зі стилем. Для цього в місті генерації рядку для текстового віджету необхідно додати атрибут color в блок і через формат передавати туди колір тексту для поточного стилю.
static void
_ui_update(UIData *ui, watch_time_h watch_time)
{
...
Style *style = &styles[ui->style_index];
char *color = style->digits_color;
snprintf(text,
BUF_SIZE,
"<font font_size=80 color=#%s>"
"<align=center>%02d:%02d:%02d</align>"
"</font>",
color,
hour24,
minute,
second);
...
}
Тепер реалізуємо функцію, в якій у відповідності з поточим стилем, буде змінюватись зовнішній вигляд фонового віджету.
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);
}
}
Реалізуйте саму функцію зміни стилю фону.
static void
_bg_apperance_set(UIData *ui)
{
Style *style = &styles[ui->style_index];
if (style->is_image == EINA_TRUE)
{
const int BUF_SIZE = 256;
char image_path[BUF_SIZE] = {0,};
_file_abs_resource_path_get(style->image_name, image_path, BUF_SIZE);
elm_bg_file_set(ui->bg, image_path, NULL);
}
else
{
char *image = NULL;
elm_bg_file_get(ui->bg, &image, NULL);
if (image)
elm_bg_file_set(ui->bg, NULL, NULL);
elm_bg_color_set(ui->bg, style->bg_r, style->bg_g, style->bg_b);
}
}
У цій функції береться поточний стиль, а потім віджету встановлюється фонове зображення або колір. Як ви вже могли помітити, в разі використання кольорового стилю, використовуються дві функції одночасно. Як говорилось раніше, віджет фону може одночасно використовувати тільки щось одне: або колір, або зображення. Краще використовувати зображення. Таким чином, програма має виконуватись в описаній нижче послідовності.
Якщо стиль має зображення у якості фону, то візьміть повний шлях до зображення і встановіть його віджету.
Якщо стиль має колір у якості фону, то спочатку потрібно прибрати зображення, якщо воно було встановлено. Видалення зображення у віджеті фоні проводиться тією ж функцією, що і встановлення зображення, тільки замість шляху до функції необхідно передати NULL.
Замініть встановлення статичного кольору для віджету фону на вашу функцію, тепер функція створення bg-віджету виглядає наступним чином:
static void
_bg_create(UIData *ui, int width, int height)
{
ui->bg = elm_bg_add(ui->win);
evas_object_resize(ui->bg, width, height);
_bg_apperance_set(ui);
evas_object_show(ui->bg);
}
І останнє, для зміни стилю циферблату, реалізуйте обробник натискання на текстовий віджет. У текстового віджета нема смарт колбеку на подію клік, тому аби зараз не створювати окрему кнопку, скористайтесь колбеком на подію дотику до віджету - EVAS_CALLBACK_MOUSE_DOWN.
У реальному циферблаті необхідно було б створити окрему кнопку, оскільки подія початку дотику не зовсім відображає клік, але для цього демо згодиться і таке рішення.
static void
_label_create(UIData *ui, int width, int height)
{
...
evas_object_event_callback_add(ui->label, EVAS_CALLBACK_MOUSE_DOWN, down_cb, ui);
}
Реалізуйте сам обробник:
static void
down_cb(void *data, Evas *evas, Evas_Object *obj, void *event)
{
UIData *ui = data;
int styles_count = EINA_C_ARRAY_LENGTH(styles);
ui->style_index = (ui->style_index + 1) % styles_count;
_watch_update(ui, NULL);
_bg_apperance_set(ui);
}
У цій функції циклічно змінюється індекс поточного стилю і викликається функція для оновлення цифр, де змінюється колір цифр, а також викликається функція для оновлення зовнішнього вигляду фону. Тепер можете запустити ваш циферблат.
У вас має вийти циферблат з безліччю стилів. Зміни проходять після дотику в області цифр, у кінці відео видно, що якщо відбувається дотик поза цифрою, то нічого не відбувається.
Ми згадували, що у віджету фону є можливість налаштувати спосіб відображення зображення, якщо його розмір буде відрізнятись від розміру віджету.
Для цих цілей, використовується наступна функція:
elm_bg_option_set(Evas_Object *bg, Elm_Bg_Option option);
Другий параметром передається сам спосіб відображення. Крім того, у вас є можливість дізнатись, який режим використовується у даний момент, для цього скористайтесь функцією:
Elm_Bg_Option elm_bg_option_get(const Evas_Object *bg);
Візьміть таке невелике зображення і подивіться, що відбувається при різних способах відображення.
ELM_BG_OPTION_CENTER — зображення буде розташоване по середині віджету.
ELM_BG_OPTION_SCALE — зображення буде розтягуватись зі збереженням співвідношення сторін, доти доки сторона з меншим розміром не розтягнеться до розмірів віджету.
ELM_BG_OPTION_STRETCH — зображення буде розтягуватись без збереження співвідношення сторін.
ELM_BG_OPTION_TILE — область віджету фону буде замощена зображеннями.
Якщо ви не будете встановлювати режим віджету, то по замовчанню буде використано режим - ELM_BG_OPTION_SCALE.
Повний код даного уроку ви можете скачати тут WearLesson029