Опубліковано: 25 Жовтня 2017
Віджет фону (Bg)

У цьому уроку мова піде про спеціальний 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) і фонове зображення, як на картинці нижче.

nw_029_02_en

6. Білі числа (#ffffff) і наступне фонове зображення.

nw_029_03_en

Тепер додайте зображення у ваш проект у папку 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);

Візьміть таке невелике зображення і подивіться, що відбувається при різних способах відображення.

nw_029_05_en

ELM_BG_OPTION_CENTER — зображення буде розташоване по середині віджету.

nw_029_06_en

ELM_BG_OPTION_SCALE — зображення буде розтягуватись зі збереженням співвідношення сторін, доти доки сторона з меншим розміром не розтягнеться до розмірів віджету.

nw_029_07_en

ELM_BG_OPTION_STRETCH — зображення буде розтягуватись без збереження співвідношення сторін.

nw_029_08_en

ELM_BG_OPTION_TILE — область віджету фону буде замощена зображеннями.

nw_029_09_en

Якщо ви не будете встановлювати режим віджету, то по замовчанню буде використано режим - ELM_BG_OPTION_SCALE.

Повний код даного уроку ви можете скачати тут WearLesson029

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *