Календарь
Разработка интерфейса пользователя
В этом разделе мы поговорим о том, как создать календарь с помощью библиотеки i18n_ucalendar_h.
Создайте новый проект 'CalendarSample'. Откройте файл исходного кода внесите следующие изменения в начале файла.
#include "calendarsample.h" #include <utils_i18n.h> typedef struct appdata { Evas_Object *win; Evas_Object *conform; Evas_Object *label; Evas_Object *label_day[6][7]; char *tzid; i18n_ucalendar_h ucal; } appdata_s;
label_day — это метка, предназначенная для отображения даты. В выделенном пространстве будет отображаться 7 столбцов по горизонтали и 6 строк по вертикали.
В переменной tzid будет храниться временная зона.
В переменной ucal будут храниться текущие дата и время.
Добавьте функцию выше create_base_gui(). Эта функция добавит контролы к таблице.
static void my_table_pack(Evas_Object *table, Evas_Object *child, int x, int y, int w, int h) { evas_object_size_hint_align_set(child, 0.5, 0.5); evas_object_size_hint_weight_set(child, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); elm_table_pack(table, child, x, y, w, h); evas_object_show(child); }
Далее, добавьте код в конец функции create_base_gui(). Этот код создает контролы Box и Table, а также добавляет метку Label.
/* Conformant */ /*ad->conform = elm_conformant_add(ad->win); elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW); elm_win_indicator_opacity_set(ad->win, ELM_WIN_INDICATOR_OPAQUE); evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); elm_win_resize_object_add(ad->win, ad->conform); evas_object_show(ad->conform);*/ /* Box to put the table in so we can bottom-align the table * window will stretch all resize object content to win size */ Evas_Object *box = elm_box_add(ad->win); evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); elm_win_resize_object_add(ad->win, box); evas_object_show(box); /* Table */ Evas_Object *table = elm_table_add(ad->win); /* Make table homogenous - every cell will be the same size */ elm_table_homogeneous_set(table, EINA_TRUE); /* Set padding of 10 pixels multiplied by scale factor of UI */ elm_table_padding_set(table, 10 * elm_config_scale_get(), 10 * elm_config_scale_get()); /* Let the table child allocation area expand within in the box */ evas_object_size_hint_weight_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); /* Set table to fiill width but align to bottom of box */ evas_object_size_hint_align_set(table, EVAS_HINT_FILL, 0.0); elm_box_pack_end(box, table); evas_object_show(table); { /* Label*/ ad->label = elm_label_add(ad->win); elm_object_text_set(ad->label, "<align=center>Calendar Sample</align>"); my_table_pack(table, ad->label, 0, 0, 7, 1); for(int j=0; j < 6; j++) { for(int i=0; i < 7; i++) { ad->label_day[j][i] = elm_label_add(ad->win); elm_object_text_set(ad->label_day[j][i], "."); my_table_pack(table, ad->label_day[j][i], i, j + 2, 1, 1); } } } /* Show window after base gui is set up */ evas_object_show(ad->win);
С помощью двух циклов for, мы создаем метку с 6 столбцами и 7 строками.
Запустите пример. Символ '.' отображает вновь созданные метки.
Отображение текущей даты и времени
В этом разделе мы создадим объект i18n_ucalendar_h и отобразим текущую дату и время на экране. Добавьте две функции выше create_base_gui().
static i18n_ucalendar_h create_time(char *tzid) { i18n_ucalendar_h ucal; i18n_uchar *_tzid = (i18n_uchar*)calloc(strlen(tzid) + 1, sizeof(i18n_uchar)); i18n_ustring_copy_ua(_tzid, tzid); int len = i18n_ustring_get_length(_tzid); int ret = i18n_ucalendar_create(_tzid, len, "en_US", I18N_UCALENDAR_TRADITIONAL, &ucal); return ucal; } static char* time2string(i18n_ucalendar_h ucal) { int year, month, day, hour, minute, second; i18n_ucalendar_get(ucal, I18N_UCALENDAR_YEAR, &year); i18n_ucalendar_get(ucal, I18N_UCALENDAR_MONTH, &month); i18n_ucalendar_get(ucal, I18N_UCALENDAR_DATE, &day); i18n_ucalendar_get(ucal, I18N_UCALENDAR_HOUR, &hour); i18n_ucalendar_get(ucal, I18N_UCALENDAR_MINUTE, &minute); i18n_ucalendar_get(ucal, I18N_UCALENDAR_SECOND, &second); char *buf = malloc(100); sprintf(buf, "Now :%04d-%02d-%02d %02d:%02d:%02d", year, month + 1, day, hour, minute, second); return buf; }
create_time() - это функция, которая создает и затем возвращает объект i18n_ucalendar_h object, а time2string() - это функция, которая превращает дату, сохраненную в объекте i18n_ucalendar_h в строку и возвращает строку. Добавьте код в конце функции create_base_gui().
evas_object_show(ad->win); system_settings_get_value_string(SYSTEM_SETTINGS_KEY_LOCALE_TIMEZONE,&ad->tzid); ad->ucal = create_time(ad->tzid); char *buf = time2string(ad->ucal); elm_object_text_set(ad->label, buf); }
Запрос временной зоны осуществляетс с помощью функции system_settings_get_value_string(). Создайте объект i18n_ucalendar_h с помощью функции create_time(). Преобразуйте дату и время, сохраненные в объекте i18n_ucalendar_h в одиночную строку с помощью функции time2string().
Запустите проект снова. Дата и время отображаются в метке.
Расчет календарных дат
В этом разделе мы поговорим о том, как определить день недели первого дня текущего месяца и ввести дату в массив меток. Создайте функцию выше create_base_gui().
static void draw_calendar(appdata_s *ad) { int date, month, dow, days, is_leap; int max_day[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; i18n_ucalendar_set(ad->ucal, I18N_UCALENDAR_DATE, 1); i18n_ucalendar_get(ad->ucal, I18N_UCALENDAR_MONTH, &month); i18n_ucalendar_get(ad->ucal, I18N_UCALENDAR_DAY_OF_WEEK, &dow); days = max_day[month]; if( month == 1 ) { i18n_ucalendar_get(ad->ucal, I18N_UCALENDAR_IS_LEAP_MONTH, &is_leap); if( is_leap == 1 ) days = 29; } int i=0, j=0; char buf[10]; i = dow - 1; for(int d=1; d <= days; d++) { sprintf(buf, "%d", d); elm_object_text_set(ad->label_day[ j][i], buf); i ++; if( i >= 7 ) { i = 0; j ++; } } }
max_day[] - это массив, в котором хранится максимальное количество дней в месяцах с января по декабрь.
i18n_ucalendar_set() - это API, который определяет новые значения для определенного элемента объекта i18n_ucalendar_h.
i18n_ucalendar_get() - это API, который возвращает значение определенного элемента объекта i18n_ucalendar_h.
Если год високосный, то в феврале будет 29 дней.
Добавьте строчку в конце функции create_base_gui().
elm_object_text_set(ad->label, buf); draw_calendar(ad); }
Запустите пример. На экране будет отображаться календарь.
Отображение текущей даты
В этом разделе мы реализуем возможность заключения текущей даты в квадратные скобки. Добавьте строчку в функцию draw_calendar().
static void draw_calendar(appdata_s *ad) { int date, month, dow, days, is_leap; int max_day[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; i18n_ucalendar_get(ad->ucal, I18N_UCALENDAR_DATE, &date); i18n_ucalendar_set(ad->ucal, I18N_UCALENDAR_DATE, 1); i18n_ucalendar_get(ad->ucal, I18N_UCALENDAR_MONTH, &month); i18n_ucalendar_get(ad->ucal, I18N_UCALENDAR_DAY_OF_WEEK, &dow); days = max_day[month]; if( month == 1 ) { i18n_ucalendar_get(ad->ucal, I18N_UCALENDAR_IS_LEAP_MONTH, &is_leap); if( is_leap == 1 ) days = 29; } int i=0, j=0; char buf[10]; i = dow - 1; for(int d=1; d <= days; d++) { sprintf(buf, "%d", d); if( d == date ) sprintf(buf, "[%d]", d); elm_object_text_set(ad->label_day[ j][i], buf); ~
Мы запрашиваем текущую дату с помощью функции i18n_ucalendar_get() и сохраняем ее в переменной.
Запустите пример. Текущая дата заключена в квадратные скобки.