Menu screen items are now displayed in a circular pattern and not as a straight list anymore

This commit is contained in:
Th3maz1ng 2023-11-04 16:28:26 +01:00
parent 967913d8df
commit 598feba07a
2 changed files with 115 additions and 12 deletions

View File

@ -10,6 +10,49 @@
#define array_size(array) (sizeof(array)/sizeof(array[0]))
static void item_container_scroll_event_cb(lv_event_t *e)
{
lv_obj_t * item_container = lv_event_get_target(e);
lv_area_t item_container_bounding_box;
lv_obj_get_coords(item_container, &item_container_bounding_box);
lv_coord_t cont_y_center = item_container_bounding_box.y1 - 25 + lv_area_get_height(&item_container_bounding_box) / 2;
lv_coord_t r = lv_obj_get_height(item_container) * 7 / 10;
uint32_t i;
uint32_t child_cnt = lv_obj_get_child_cnt(item_container);
for(i = 0; i < child_cnt; i++)
{
lv_obj_t * child = lv_obj_get_child(item_container, i);
lv_area_t child_a;
lv_obj_get_coords(child, &child_a);
lv_coord_t child_y_center = child_a.y1 + lv_area_get_height(&child_a) / 2;
lv_coord_t diff_y = child_y_center - cont_y_center;
diff_y = LV_ABS(diff_y);
/*Get the x of diff_y on a circle.*/
lv_coord_t x;
/*If diff_y is out of the circle use the last point of the circle (the radius)*/
if(diff_y >= r)
{
x = r;
}
else
{
/*Use Pythagoras theorem to get x from radius and y*/
uint32_t x_sqr = r * r - diff_y * diff_y;
lv_sqrt_res_t res;
lv_sqrt(x_sqr, &res, 0x8000); /*Use lvgl's built in sqrt root function*/
x = r - res.i;
}
/*Translate the item by the calculated X coordinate*/
lv_obj_set_style_translate_x(child, x, 0);
}
}
static void menu_item_cb(lv_event_t *e)
{
lv_obj_t *item = lv_event_get_target(e);
@ -100,7 +143,8 @@ static void menu_screen_add_item(MenuScreen_t * const menuScreen, uint8_t positi
lv_obj_set_user_data(item_btn, (void *)(uint32_t)position);
lv_obj_set_size(item_btn, itemImg->header.w, itemImg->header.h);
lv_obj_add_flag(item_btn, LV_OBJ_FLAG_ADV_HITTEST | LV_OBJ_FLAG_CLICKABLE);
lv_obj_set_pos(item_btn, 42, 52 * position);
const uint8_t left_margin = 10;
lv_obj_set_pos(item_btn, left_margin, 52 * position);
lv_img_set_src(item_btn, itemImg);
lv_obj_add_event_cb(item_btn, itemClickEventCb, LV_EVENT_CLICKED, (void *)menuScreen);
@ -109,7 +153,7 @@ static void menu_screen_add_item(MenuScreen_t * const menuScreen, uint8_t positi
lv_obj_set_user_data(item_label, (void *)(uint32_t)position);
lv_label_set_text_static(item_label, itemTitle);
lv_obj_set_style_text_font(item_label, &lv_font_montserrat_16, LV_PART_MAIN);
lv_obj_set_pos(item_label, 84+12, 15 + 52 * position);
lv_obj_set_pos(item_label, 42 + left_margin + 12, 15 + 52 * position);
lv_obj_set_style_text_color(item_label, lv_color_make(145, 145, 145), LV_PART_MAIN);
lv_obj_set_ext_click_area(item_label, 10);
lv_obj_add_flag(item_label, LV_OBJ_FLAG_CLICKABLE);
@ -160,10 +204,13 @@ void menu_screen_create(MenuScreen_t * const menuScreen)
lv_obj_set_pos(menuScreen->scrollItemContainer, 0, 50);
lv_obj_set_style_pad_all(menuScreen->scrollItemContainer, 0, LV_PART_MAIN);
lv_obj_set_style_pad_top(menuScreen->scrollItemContainer, 10, LV_PART_MAIN);
lv_obj_set_style_pad_bottom(menuScreen->scrollItemContainer, 20, LV_PART_MAIN);
lv_obj_set_style_pad_bottom(menuScreen->scrollItemContainer, 30, LV_PART_MAIN);
lv_obj_set_style_radius(menuScreen->scrollItemContainer, 0, LV_PART_MAIN);
lv_obj_set_style_border_width(menuScreen->scrollItemContainer, 0, LV_PART_MAIN);
lv_obj_set_style_pad_right(menuScreen->scrollItemContainer, 15, LV_PART_SCROLLBAR);
lv_obj_set_scrollbar_mode(menuScreen->scrollItemContainer, LV_SCROLLBAR_MODE_OFF);
lv_obj_set_scroll_dir(menuScreen->scrollItemContainer, LV_DIR_VER);
lv_obj_add_event_cb(menuScreen->scrollItemContainer, &(item_container_scroll_event_cb), LV_EVENT_SCROLL, NULL);
menu_screen_add_item(menuScreen, 0, &watch_menu_clock_icon, translation_get_word(TRANSLATION_WATCH), &(menu_item_cb));
menu_screen_add_item(menuScreen, 1, &watch_menu_alarm_icon, translation_get_word(TRANSLATION_ALARM), &(menu_item_cb));
@ -182,6 +229,12 @@ void menu_screen_create(MenuScreen_t * const menuScreen)
//We register the event callback to handle the cleanup
lv_obj_add_event_cb(menuScreen->display, &(cleanup_event_cb), LV_EVENT_DELETE, menuScreen);
//Lets restore the previous scrolling position
lv_obj_scroll_to_y(menuScreen->scrollItemContainer, !menuScreen->lastScrollPosition ? 1 : menuScreen->lastScrollPosition, LV_ANIM_OFF);
//Finally update the menu item's position manually
lv_event_send(menuScreen->scrollItemContainer, LV_EVENT_SCROLL, NULL);
}
void menu_screen_destroy(MenuScreen_t * const menuScreen)

View File

@ -10,6 +10,49 @@
#define array_size(array) (sizeof(array)/sizeof(array[0]))
static void item_container_scroll_event_cb(lv_event_t *e)
{
lv_obj_t * item_container = lv_event_get_target(e);
lv_area_t item_container_bounding_box;
lv_obj_get_coords(item_container, &item_container_bounding_box);
lv_coord_t cont_y_center = item_container_bounding_box.y1 - 25 + lv_area_get_height(&item_container_bounding_box) / 2;
lv_coord_t r = lv_obj_get_height(item_container) * 7 / 10;
uint32_t i;
uint32_t child_cnt = lv_obj_get_child_cnt(item_container);
for(i = 0; i < child_cnt; i++)
{
lv_obj_t * child = lv_obj_get_child(item_container, i);
lv_area_t child_a;
lv_obj_get_coords(child, &child_a);
lv_coord_t child_y_center = child_a.y1 + lv_area_get_height(&child_a) / 2;
lv_coord_t diff_y = child_y_center - cont_y_center;
diff_y = LV_ABS(diff_y);
/*Get the x of diff_y on a circle.*/
lv_coord_t x;
/*If diff_y is out of the circle use the last point of the circle (the radius)*/
if(diff_y >= r)
{
x = r;
}
else
{
/*Use Pythagoras theorem to get x from radius and y*/
uint32_t x_sqr = r * r - diff_y * diff_y;
lv_sqrt_res_t res;
lv_sqrt(x_sqr, &res, 0x8000); /*Use lvgl's built in sqrt root function*/
x = r - res.i;
}
/*Translate the item by the calculated X coordinate*/
lv_obj_set_style_translate_x(child, x, 0);
}
}
static void menu_item_cb(lv_event_t *e)
{
uint64_t icon_id = (uint64_t)e->user_data;
@ -95,11 +138,12 @@ void menu_screen_init(MenuScreen_t * const menuScreen)
static void menu_screen_add_item(lv_obj_t *scroll_item_container, uint8_t position, const lv_img_dsc_t *itemImg,const char *itemTitle, lv_event_cb_t itemClickEventCb)
{
//We add the image button with the icon of the item
//lv_obj_t *item_btn = lv_imgbtn_create(scroll_item_container);
lv_obj_t *item_btn = lv_img_create(scroll_item_container);
lv_obj_set_user_data(item_btn, (void *)(uint32_t)position);
lv_obj_set_size(item_btn, itemImg->header.w, itemImg->header.h);
lv_obj_add_flag(item_btn, LV_OBJ_FLAG_ADV_HITTEST | LV_OBJ_FLAG_CLICKABLE);
lv_obj_set_pos(item_btn, 42, 52 * position);
const uint8_t left_margin = 10;
lv_obj_set_pos(item_btn, left_margin, 52 * position);
//lv_imgbtn_set_src(item_btn, LV_IMGBTN_STATE_RELEASED, NULL, itemImg, NULL);
lv_img_set_src(item_btn, itemImg);
lv_obj_add_event_cb(item_btn, itemClickEventCb, LV_EVENT_CLICKED, (void *)(uint64_t)position);
@ -108,7 +152,7 @@ static void menu_screen_add_item(lv_obj_t *scroll_item_container, uint8_t positi
lv_obj_t *item_label = lv_label_create(scroll_item_container);
lv_label_set_text_static(item_label, itemTitle);
lv_obj_set_style_text_font(item_label, &lv_font_montserrat_16, LV_PART_MAIN);
lv_obj_set_pos(item_label, 84+12, 15 + 52 * position);
lv_obj_set_pos(item_label, 42 + left_margin + 12, 15 + 52 * position);
lv_obj_set_style_text_color(item_label, lv_color_make(145, 145, 145), LV_PART_MAIN);
lv_obj_set_ext_click_area(item_label, 10);
lv_obj_add_flag(item_label, LV_OBJ_FLAG_CLICKABLE);
@ -160,10 +204,13 @@ void menu_screen_create(MenuScreen_t * const menuScreen)
lv_obj_set_pos(menuScreen->scrollItemContainer, 0, 50);
lv_obj_set_style_pad_all(menuScreen->scrollItemContainer, 0, LV_PART_MAIN);
lv_obj_set_style_pad_top(menuScreen->scrollItemContainer, 10, LV_PART_MAIN);
lv_obj_set_style_pad_bottom(menuScreen->scrollItemContainer, 20, LV_PART_MAIN);
lv_obj_set_style_pad_bottom(menuScreen->scrollItemContainer, 30, LV_PART_MAIN);
lv_obj_set_style_radius(menuScreen->scrollItemContainer, 0, LV_PART_MAIN);
lv_obj_set_style_border_width(menuScreen->scrollItemContainer, 0, LV_PART_MAIN);
lv_obj_set_style_pad_right(menuScreen->scrollItemContainer, 15, LV_PART_SCROLLBAR);
lv_obj_set_scrollbar_mode(menuScreen->scrollItemContainer, LV_SCROLLBAR_MODE_OFF);
lv_obj_set_scroll_dir(menuScreen->scrollItemContainer, LV_DIR_VER);
lv_obj_add_event_cb(menuScreen->scrollItemContainer, &(item_container_scroll_event_cb), LV_EVENT_SCROLL, NULL);
menu_screen_add_item(menuScreen->scrollItemContainer, 0, &watch_menu_clock_icon, "Watch", &(menu_item_cb));
menu_screen_add_item(menuScreen->scrollItemContainer, 1, &watch_menu_alarm_icon, "Alarm", &(menu_item_cb));
@ -177,11 +224,14 @@ void menu_screen_create(MenuScreen_t * const menuScreen)
//menu_screen_add_item(scroll_item_container, 6, &watch_menu_contacts_icon, "Contacts", &(menu_item_cb));
menu_screen_add_item(menuScreen->scrollItemContainer, 6, &watch_menu_settings_icon, "Settings", &(menu_item_cb));
//Lets restore the previous scrolling position
lv_obj_scroll_to_y(menuScreen->scrollItemContainer, menuScreen->lastScrollPosition, LV_ANIM_OFF);
//We register the event callback to handle the cleanup
lv_obj_add_event_cb(menuScreen->display, &(cleanup_event_cb), LV_EVENT_DELETE, menuScreen);
//Lets restore the previous scrolling position
lv_obj_scroll_to_y(menuScreen->scrollItemContainer, !menuScreen->lastScrollPosition ? 1 : menuScreen->lastScrollPosition, LV_ANIM_OFF);
//Finally update the menu item's position manually
lv_event_send(menuScreen->scrollItemContainer, LV_EVENT_SCROLL, NULL);
}
void menu_screen_destroy(MenuScreen_t * const menuScreen)