С этого урока мы начинаем создавать следующее демо приложение. В котором мы научимся создавать интерфейс с постраничным просмотром содержимого. Для этого нам понадобиться контейнер-скроллер, контейнер-коробок (Box), контейнер-макет (Layout), виджеты-изображения и виджет индексации для индикации активной страницы.
В этом уроке мы подробно разберем контейнер-коробок и познакомимся с его возможностями. Cоздадим сам контейнер и наполним его содержимым.
Как уже говорилось контейнер-коробок это компонент который позволяет помещать в себя графические элементы в линейном порядке, это может быть горизонтальная или вертикальная компоновка (по-умолчанию). При этом они индексируются слева направо при горизонтальной компоновке и сверху вниз при вертикальной. Вы можете настраивать способ расположения вложенных в коробок компонентов, и расстояние между соседними компонентами.
Ниже представлена схема расположения компонентов помещаемых в контейнер-коробок.
Коробок позволяет помещать в себя любое количество различных элементов, но все элементы должны предствлять из себя объекты Evas (Evas_Object).
Этот контейнер часто используется вместе со скроллером поскольку зачастую в коробок помещают значительно больше элементов чем может вместиться на экране и возникает необходимость в прокручиваемой области.
Теперь приступим к реализации программы.
Как и в прошлых двух демо-приложениях возьмем тот же начальный шаблон для написания 3го демо.
Начнем с добавления указателя для нашего контейнера-коробка в структуру с главными виджетами. Контейнер коробок является Evas_Object как и все контейнера и виджеты в Elementary.
Evas_Object *box;
Получим следующее содержимое нашей структуры с графическими компонентами.
typedef struct _UIData {
Evas_Object *win;
Evas_Object *conform;
Evas_Object *box;
} UIData;
Создадим отдельную функцию для создания и настройки контейнера в нашем приложении.
static void
_box_create(UIData *ui)
{
}
Для создания контейнера-коробка вызываем внутри следующую функцию:
ui->box = elm_box_add(ui->conform);
Как параметр функция принимает указатель на компонент-родитель который будет отвечать за удаление коробка.
Теперь можно наполнить контейнер. Давайте для начала добавим пару кнопок и посмотрим что получиться. Создание кнопок мы рассматривали в уроке 14 поэтому особо на кнопках останавливаться не будем. Просто для создания вы можете использовать следующий код, и добавить его после создания коробка в функцию _box_create().
static void
_box_create(UIData *ui)
{
...
Evas_Object *button = NULL;
for (int i = 0; i < 2; ++i)
{
button = elm_button_add(ui->box);
evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL);
elm_object_text_set(button, "Кнопка");
evas_object_show(button);
elm_box_pack_end(ui->box, button);
}
}
Здесь мы в цикле просто создаем 2 кнопки и помещаем их в сам коробок.
Добавление содержимого в контейнер здесь осуществляется вызовом функции:
elm_box_pack_end(Evas_Object *obj, Evas_Object *insert);
Первым параметром передается указатель на коробок в который добавить виджет, а вторым – указатель на компонент который необходимо добавить.
Показанная выше функция добавляет элемент на последнее место в коробке. Функционал библиотеки Elementary позволяет также добавить элемент другими способами:
Добавление в начало коробка:
elm_box_pack_start(Evas_Object *box, Evas_Object *insert);
А также вставка компонента перед и после другого указанного компонента следующими функциями.
elm_box_pack_before(Evas_Object *box, Evas_Object *insert, Evas_Object *before);
elm_box_pack_after(Evas_Object *box, Evas_Object *insert, Evas_Object *after);
Последние функции принимают 3м аргументом указатель на объект Evas перед/после которого необходимо вставить новый компонент.
Таким образом используя указанные 4 функции вы можете контролировать порядок расположения объектов в коробке.
Теперь давайте отобразим наш коробок.
static void
_box_create(UIData *ui)
{
...
evas_object_show(ui->box);
}
Теперь вызовем нашу функцию создания коробка и поместим его в конформант после создания.
static void
_conformant_create(UIData *ui)
{
...
_box_create(ui);
elm_object_content_set(ui->conform, ui->box);
...
}
Запускаем приложение.
У нас получилась следующая картина.
Как и ожидалось на экране появилось две кнопки занимающие все свободное пространство расположенные вертикально поскольку мы не указывали ориентацию.
Evas позволяет устанавливать цвет любому объекту прорисовки, давайте воспользуемся этой возможностью что бы немного подкрасить последнюю кнопку для лучшего понимания границ объекта. Если компонент который вы собрались красить уже имеет цвет, как в нашем случае, то в итоге цвета смешаются, например мы установим желтый цвет и таким образом ожидается зеленая кнопка.
Для окраски объекта Evas воспользуемся следующей функцией после цикла с созданием кнопок.
evas_object_color_set(button, 255, 255, 0, 255);
Функция принимает указатель на объект которому необходимо указать цвет, и 4 компоненты цвета – красный, зеленый, синий, прозрачность. Все параметры допускаются в диапазоне от 0 до 255 включительно. Последний компонент отвечает за прозрачность поэтому у вас есть возможность сделать любой компонент полупрозрачным или даже невидимым при помощи цвета.
Итак после окраски мы получили следующий вид нашего приложения.
Как видно обе кнопки делят доступное им пространство поровну.
Как мы говорили ранее коробок имеет два варианта использования: вертикальный и горизонтальный. Давайте изменим наш контейнер с вертикального на горизонтальный. Используем следующую функцию.
elm_box_horizontal_set(ui->box, EINA_TRUE);
Функция принимает указатель на коробок которому необходимо поменять конфигурацию и логическое значение, где EINA_TRUE - отвечает за установку горизонтального расположения, а EINA_FALSE – за вертикальное.
Запускаем приложение.
Теперь элементы располагаются горизонтально как мы и указали.
Еще одна возможность коробка это установка расстояния (padding) между соседними компонентами. Давайте установим расстояние в 10 пикселей между горизонтальными элементами. Это осуществляется следующей функцией:
elm_box_padding_set(ui->box, 10, 0);
Функция принимает указатель на коробок которому необходимо поменять отступы между соседними компонентами и размеры самих отступов в пикселях горизонтальный и вертикальный соответственно.
Выше показан результат добавления отступов между элементами.
Для того чтобы полноценно разобраться с коробком, необходимо разобраться с параметрами веса и расположения объектов Evas.
Вес объекта необходим для того что бы изменять пропорции размеров компонентов находящихся в коробке. Так например если одна кнопка имеет вес равным 1, а вторая кнопка вес равным 2, то в итоге кнопки коробка будут весить 3, следовательно первая кнопка будет занимать треть (1/3) размера контейнера, а 2я кнопка две трети(2/3). В данном случае если размер коробка 360 пикселей, то 1я кнопка будет 120 пикселей, а вторая 240 пикселей.
Вес указывается для горизонтальной и вертикальной плоскости и будет использоваться тот или другой в зависимости от режима контейнера-коробка. Для изменения веса объекта используется следующая функция:
evas_object_size_hint_weight_set(button, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
По умолчанию вес объекта равен 0 по обоим осям. Следовательно объект будет занимать минимальную область.
Ниже представлены различные комбинации для веса первой и второй кнопки при разных весах объектов.
Параметры:
Горизонтальный режим коробка:
Кнопка 1: горизонтальный вес 1.0, вертикальный – 0.0.
Кнопка 2: горизонтальный вес 2.0, вертикальный – 0.0.
Параметры:
Горизонтальный режим коробка:
Кнопка 1: горизонтальный вес 0.6, вертикальный – 0.5.
Кнопка 2: горизонтальный вес 0.2, вертикальный – 1.5.
В данных двух случаях вертикальный вес кнопок игнорируется поскольку коробок является горизонтальным.
Параметры:
Вертикальный режим коробка:
Кнопка 1: горизонтальный вес 0.6, вертикальный – 0.5.
Кнопка 2: горизонтальный вес 0.2, вертикальный – 1.5.
В данном случае результат немного неочевиден, поскольку кнопка 1 должна занимать ¼ размера коробка. Но это все из-за того что кнопка имеет минимальный вертикальный размер 122 пикселя следовательно свободного пространства в коробке 360 – 122 * 2 = 116 пикселей. Вот это пространство кнопки и делят в пропорции ¼ на первую кнопку и ¾ на вторую. Это получается что первая кнопка расширяется на 116 * ¼ = 29 пикселей от минимального размера, а вторая на 116 * ¾ = 87 пикселей.
Ниже показано наглядно:
Помимо веса на расположение объектов влияет параметр выравнивания. В примерах выше использовалось выравнивание типа наполнения (EVAS_HINT_FILL), при этом виджет занимает все предоставляемое место которое рассчитывается из веса объектов.
Давайте анологично весу посмотрим что будет происходить при изменении выравнивания объекта, при этом мы будем использовать одинаковый вес объектов.
Параметры выравнивания также указываются для горизонтальной и вертикальной плоскости и будет использоваться тот или другой в зависимости от режима контейнера-коробка. Для изменения выравнивания объекта используется следующая функция:
evas_object_size_hint_align_set(button, EVAS_HINT_FILL, EVAS_HINT_FILL);
Функция принимает вещественное число от 0 до 1. Где 0 – это левое/верхнее положение, а 1 – это правое/нижнее положение. Так для расположения посредине используются значения равные 0.5. По умолчанию объект использует выравнивание по центру.
Если в функцию передать специфическое значение EVAS_HINT_FILL который равен -1, то объект будет не выравниваться в области, а растягиваться по ней. Если не использовать EVAS_HINT_FILL для выравнивания то объект будет иметь минимальный размер виджета.
Так для выравнивания по умолчанию, то есть по середине кнопки в коробке будут распологаться следующим образом:
Теперь давайте посмотрим что будет если использовать следующие параметры вырванивания для кнопок.
Кнопка 1: горизонтальное выравнивание 0.2, вертикальное – 0.5.
Кнопка 2: горизонтальное выравнивание 0.5, вертикальное – 0.0.
Итак первая кнопка (синяя) располагается в относительной координате 0.2 по горизонтали и посредине (0.5) по вертикали. В отведенной для этой кнопки зоне, а вторая кнопка (зеленая) расположена посредине предоставленного пространства по горизонтали, и в максимально допустимом верхнем положении по вертикали (0.0).
Теперь давайте изменим значение веса для виджетов и посмотрим что получится при таких параметрах:
Кнопка 1: горизонтальное выравнивание 0.2, вертикальное – 0.5.
Кнопка 1: горизонтальный вес 1.0, вертикальный – 1.
Кнопка 2: горизонтальное выравнивание 0.5, вертикальное – 0.0.
Кнопка 2: горизонтальный вес 1.0, вертикальный – 2.
Теперь вы сможете применить параметры веса и выравнивания по требованиям вашего приложения.