diff --git a/src/W800_SDK_v1.00.10/app/gfx/menu_screen.c b/src/W800_SDK_v1.00.10/app/gfx/menu_screen.c index f02ea4e..3c452cc 100644 --- a/src/W800_SDK_v1.00.10/app/gfx/menu_screen.c +++ b/src/W800_SDK_v1.00.10/app/gfx/menu_screen.c @@ -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) diff --git a/src/lvgl_win_sim/lv_port_win_codeblocks/menu_screen.c b/src/lvgl_win_sim/lv_port_win_codeblocks/menu_screen.c index 1a33964..a10d025 100644 --- a/src/lvgl_win_sim/lv_port_win_codeblocks/menu_screen.c +++ b/src/lvgl_win_sim/lv_port_win_codeblocks/menu_screen.c @@ -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)