It is now possible to swipe from right to left on the menu screen to open back the previously used application
This commit is contained in:
parent
68e1accde7
commit
8b16cf98aa
@ -8,8 +8,6 @@
|
|||||||
#include "music_player_screen.h"
|
#include "music_player_screen.h"
|
||||||
#include "translation.h"
|
#include "translation.h"
|
||||||
|
|
||||||
#define array_size(array) (sizeof(array)/sizeof(array[0]))
|
|
||||||
|
|
||||||
static void item_container_scroll_event_cb(lv_event_t *e)
|
static void item_container_scroll_event_cb(lv_event_t *e)
|
||||||
{
|
{
|
||||||
lv_obj_t * item_container = lv_event_get_target(e);
|
lv_obj_t * item_container = lv_event_get_target(e);
|
||||||
@ -32,41 +30,30 @@ static void item_container_scroll_event_cb(lv_event_t *e)
|
|||||||
lv_coord_t diff_y = child_y_center - cont_y_center;
|
lv_coord_t diff_y = child_y_center - cont_y_center;
|
||||||
diff_y = LV_ABS(diff_y);
|
diff_y = LV_ABS(diff_y);
|
||||||
|
|
||||||
/*Get the x of diff_y on a circle.*/
|
// Get the x of diff_y on a circle.
|
||||||
lv_coord_t x;
|
lv_coord_t x;
|
||||||
/*If diff_y is out of the circle use the last point of the circle (the radius)*/
|
// If diff_y is out of the circle use the last point of the circle (the radius)
|
||||||
if(diff_y >= r)
|
if(diff_y >= r)
|
||||||
{
|
{
|
||||||
x = r;
|
x = r;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*Use Pythagoras theorem to get x from radius and y*/
|
// Use Pythagoras theorem to get x from radius and y
|
||||||
uint32_t x_sqr = r * r - diff_y * diff_y;
|
uint32_t x_sqr = r * r - diff_y * diff_y;
|
||||||
lv_sqrt_res_t res;
|
lv_sqrt_res_t res;
|
||||||
lv_sqrt(x_sqr, &res, 0x8000); /*Use lvgl's built in sqrt root function*/
|
lv_sqrt(x_sqr, &res, 0x8000); /*Use lvgl's built in sqrt root function*/
|
||||||
x = r - res.i;
|
x = r - res.i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Translate the item by the calculated X coordinate*/
|
// Translate the item by the calculated X coordinate
|
||||||
lv_obj_set_style_translate_x(child, x, 0);
|
lv_obj_set_style_translate_x(child, x, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void menu_item_cb(lv_event_t *e)
|
static void simulate_menu_item_click(uint8_t menu_item_id)
|
||||||
{
|
{
|
||||||
lv_obj_t *item = lv_event_get_target(e);
|
switch(menu_item_id)
|
||||||
uint32_t clicked_item_id = (uint32_t) lv_obj_get_user_data(item);
|
|
||||||
MenuScreen_t *menuScreen = (MenuScreen_t*) lv_event_get_user_data(e);
|
|
||||||
|
|
||||||
LV_LOG_USER("Menu item clicked : %u", clicked_item_id);
|
|
||||||
|
|
||||||
// Give some user feedback that an item was clicked by calling the
|
|
||||||
// callback if one is registered
|
|
||||||
if(menuScreen->menuScreenOnMenuItemClickCb)
|
|
||||||
menuScreen->menuScreenOnMenuItemClickCb();
|
|
||||||
|
|
||||||
switch(clicked_item_id)
|
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
@ -108,9 +95,45 @@ static void menu_item_cb(lv_event_t *e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void menu_item_cb(lv_event_t *e)
|
||||||
|
{
|
||||||
|
lv_obj_t *item = lv_event_get_target(e);
|
||||||
|
uint32_t clicked_item_id = (uint32_t) lv_obj_get_user_data(item);
|
||||||
|
MenuScreen_t *menuScreen = (MenuScreen_t*) lv_event_get_user_data(e);
|
||||||
|
|
||||||
|
LV_LOG_USER("Menu item clicked : %u", clicked_item_id);
|
||||||
|
|
||||||
|
menuScreen->lastClickedMenuItem = clicked_item_id;
|
||||||
|
|
||||||
|
// Give some user feedback that an item was clicked by calling the
|
||||||
|
// callback if one is registered
|
||||||
|
if(menuScreen->menuScreenUserFeedbackCb)
|
||||||
|
menuScreen->menuScreenUserFeedbackCb();
|
||||||
|
|
||||||
|
// Switch application depending on the clicked menu item id
|
||||||
|
simulate_menu_item_click(clicked_item_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gesture_event_cb(lv_event_t *e)
|
||||||
|
{
|
||||||
|
MenuScreen_t *menuScreen = lv_event_get_user_data(e);
|
||||||
|
|
||||||
|
lv_dir_t gesture;
|
||||||
|
switch(gesture = lv_indev_get_gesture_dir(lv_indev_get_act()))
|
||||||
|
{
|
||||||
|
case LV_DIR_LEFT:
|
||||||
|
LV_LOG_USER("GESTURE : LEFT");
|
||||||
|
// Go back to the previously clicked application
|
||||||
|
simulate_menu_item_click(menuScreen->lastClickedMenuItem);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LV_LOG_USER("GESTURE : %u", gesture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void cleanup_event_cb(lv_event_t * e)
|
static void cleanup_event_cb(lv_event_t * e)
|
||||||
{
|
{
|
||||||
MenuScreen_t *menuScreen = e->user_data;
|
MenuScreen_t *menuScreen = lv_event_get_user_data(e);
|
||||||
menu_screen_destroy(menuScreen);
|
menu_screen_destroy(menuScreen);
|
||||||
LV_LOG_USER("cleanup");
|
LV_LOG_USER("cleanup");
|
||||||
}
|
}
|
||||||
@ -125,7 +148,7 @@ void menu_screen_init(MenuScreen_t * const menuScreen)
|
|||||||
memset(menuScreen, 0, sizeof(MenuScreen_t));
|
memset(menuScreen, 0, sizeof(MenuScreen_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void menu_screen_register_on_menu_item_click_cb(MenuScreen_t * const menuScreen, MenuScreenOnMenuItemClickCb_t menuScreenOnMenuItemClickCb)
|
void menu_screen_register_user_feedback_cb(MenuScreen_t * const menuScreen, MenuScreenUserFeedbackCb_t menuScreenUserFeedbackCb)
|
||||||
{
|
{
|
||||||
if(!menuScreen)
|
if(!menuScreen)
|
||||||
{
|
{
|
||||||
@ -133,12 +156,12 @@ void menu_screen_register_on_menu_item_click_cb(MenuScreen_t * const menuScreen,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
menuScreen->menuScreenOnMenuItemClickCb = menuScreenOnMenuItemClickCb;
|
menuScreen->menuScreenUserFeedbackCb = menuScreenUserFeedbackCb;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void menu_screen_add_item(MenuScreen_t * const menuScreen, uint8_t position, const lv_img_dsc_t *itemImg,const char *itemTitle, lv_event_cb_t itemClickEventCb)
|
static void menu_screen_add_item(MenuScreen_t * const menuScreen, 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
|
// We add the image button with the icon of the item
|
||||||
lv_obj_t *item_btn = lv_img_create(menuScreen->scrollItemContainer);
|
lv_obj_t *item_btn = lv_img_create(menuScreen->scrollItemContainer);
|
||||||
lv_obj_set_user_data(item_btn, (void *)(uint32_t)position);
|
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_set_size(item_btn, itemImg->header.w, itemImg->header.h);
|
||||||
@ -148,7 +171,7 @@ static void menu_screen_add_item(MenuScreen_t * const menuScreen, uint8_t positi
|
|||||||
lv_img_set_src(item_btn, itemImg);
|
lv_img_set_src(item_btn, itemImg);
|
||||||
lv_obj_add_event_cb(item_btn, itemClickEventCb, LV_EVENT_CLICKED, (void *)menuScreen);
|
lv_obj_add_event_cb(item_btn, itemClickEventCb, LV_EVENT_CLICKED, (void *)menuScreen);
|
||||||
|
|
||||||
//We add the click-able label with the title of the item
|
// We add the click-able label with the title of the item
|
||||||
lv_obj_t *item_label = lv_label_create(menuScreen->scrollItemContainer);
|
lv_obj_t *item_label = lv_label_create(menuScreen->scrollItemContainer);
|
||||||
lv_obj_set_user_data(item_label, (void *)(uint32_t)position);
|
lv_obj_set_user_data(item_label, (void *)(uint32_t)position);
|
||||||
lv_label_set_text_static(item_label, itemTitle);
|
lv_label_set_text_static(item_label, itemTitle);
|
||||||
@ -168,7 +191,7 @@ void menu_screen_create(MenuScreen_t * const menuScreen)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//We declare all the needed assets by the menu screen:
|
// We declare all the needed assets by the menu screen:
|
||||||
LV_IMG_DECLARE(watch_menu_clock_icon)
|
LV_IMG_DECLARE(watch_menu_clock_icon)
|
||||||
LV_IMG_DECLARE(watch_menu_dialer_icon)
|
LV_IMG_DECLARE(watch_menu_dialer_icon)
|
||||||
LV_IMG_DECLARE(watch_menu_lost_phone_icon)
|
LV_IMG_DECLARE(watch_menu_lost_phone_icon)
|
||||||
@ -180,7 +203,7 @@ void menu_screen_create(MenuScreen_t * const menuScreen)
|
|||||||
LV_IMG_DECLARE(watch_menu_messages_icon)
|
LV_IMG_DECLARE(watch_menu_messages_icon)
|
||||||
LV_IMG_DECLARE(watch_menu_compass_icon)
|
LV_IMG_DECLARE(watch_menu_compass_icon)
|
||||||
|
|
||||||
//We create our parent screen :
|
// We create our parent screen :
|
||||||
if(menuScreen->display)
|
if(menuScreen->display)
|
||||||
{
|
{
|
||||||
LV_LOG_ERROR("display should be NULL here !");
|
LV_LOG_ERROR("display should be NULL here !");
|
||||||
@ -189,7 +212,7 @@ void menu_screen_create(MenuScreen_t * const menuScreen)
|
|||||||
}
|
}
|
||||||
menuScreen->display = lv_obj_create(NULL);
|
menuScreen->display = lv_obj_create(NULL);
|
||||||
|
|
||||||
//We add the screen header
|
// We add the screen header
|
||||||
common_screen_header_component(menuScreen->display, "Menu", 50);
|
common_screen_header_component(menuScreen->display, "Menu", 50);
|
||||||
|
|
||||||
if(menuScreen->scrollItemContainer)
|
if(menuScreen->scrollItemContainer)
|
||||||
@ -223,17 +246,16 @@ void menu_screen_create(MenuScreen_t * const menuScreen)
|
|||||||
menu_screen_add_item(menuScreen, 5, &watch_menu_dialer_icon, "Phone", &(menu_item_cb));
|
menu_screen_add_item(menuScreen, 5, &watch_menu_dialer_icon, "Phone", &(menu_item_cb));
|
||||||
menu_screen_add_item(menuScreen, 6, &watch_menu_contacts_icon, "Contacts", &(menu_item_cb));*/
|
menu_screen_add_item(menuScreen, 6, &watch_menu_contacts_icon, "Contacts", &(menu_item_cb));*/
|
||||||
menu_screen_add_item(menuScreen, 5, &watch_menu_settings_icon, translation_get_word(TRANSLATION_SETTINGS), &(menu_item_cb));
|
menu_screen_add_item(menuScreen, 5, &watch_menu_settings_icon, translation_get_word(TRANSLATION_SETTINGS), &(menu_item_cb));
|
||||||
|
// We register the event callback to handle the right to left swipe gesture
|
||||||
|
lv_obj_add_event_cb(menuScreen->display, &(gesture_event_cb), LV_EVENT_GESTURE, menuScreen);
|
||||||
|
|
||||||
//Lets restore the previous scrolling position
|
// We register the event callback to handle the cleanup
|
||||||
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);
|
lv_obj_add_event_cb(menuScreen->display, &(cleanup_event_cb), LV_EVENT_DELETE, menuScreen);
|
||||||
|
|
||||||
//Lets restore the previous scrolling position
|
// Lets restore the previous scrolling position
|
||||||
lv_obj_scroll_to_y(menuScreen->scrollItemContainer, !menuScreen->lastScrollPosition ? 1 : menuScreen->lastScrollPosition, LV_ANIM_OFF);
|
lv_obj_scroll_to_y(menuScreen->scrollItemContainer, !menuScreen->lastScrollPosition ? 1 : menuScreen->lastScrollPosition, LV_ANIM_OFF);
|
||||||
|
|
||||||
//Finally update the menu item's position manually
|
// Finally update the menu item's position manually
|
||||||
lv_event_send(menuScreen->scrollItemContainer, LV_EVENT_SCROLL, NULL);
|
lv_event_send(menuScreen->scrollItemContainer, LV_EVENT_SCROLL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,7 +267,7 @@ void menu_screen_destroy(MenuScreen_t * const menuScreen)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Lets save the current scroll position
|
// Lets save the current scroll position
|
||||||
menuScreen->lastScrollPosition = lv_obj_get_scroll_y(menuScreen->scrollItemContainer);
|
menuScreen->lastScrollPosition = lv_obj_get_scroll_y(menuScreen->scrollItemContainer);
|
||||||
memset(menuScreen, 0, offsetof(MenuScreen_t, lastScrollPosition));
|
memset(menuScreen, 0, offsetof(MenuScreen_t, lastScrollPosition));
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "lvgl.h"
|
#include "lvgl.h"
|
||||||
|
|
||||||
typedef void (*MenuScreenOnMenuItemClickCb_t)(void);
|
typedef void (*MenuScreenUserFeedbackCb_t)(void);
|
||||||
|
|
||||||
// Menu screen context object
|
// Menu screen context object
|
||||||
typedef struct MenuScreen
|
typedef struct MenuScreen
|
||||||
@ -13,24 +13,40 @@ typedef struct MenuScreen
|
|||||||
lv_obj_t *scrollItemContainer;
|
lv_obj_t *scrollItemContainer;
|
||||||
// Should not be erased attributes
|
// Should not be erased attributes
|
||||||
lv_coord_t lastScrollPosition;
|
lv_coord_t lastScrollPosition;
|
||||||
MenuScreenOnMenuItemClickCb_t menuScreenOnMenuItemClickCb;
|
MenuScreenUserFeedbackCb_t menuScreenUserFeedbackCb;
|
||||||
|
uint8_t lastClickedMenuItem;
|
||||||
} MenuScreen_t;
|
} MenuScreen_t;
|
||||||
|
|
||||||
/* Initializes the menu screen context object */
|
/**
|
||||||
|
* @brief Initializes the menu screen's context object.
|
||||||
|
* @note This function has to be called first before any others.
|
||||||
|
*
|
||||||
|
* @param menuScreen a pointer to the menu screen's context structure to initialize.
|
||||||
|
*/
|
||||||
void menu_screen_init(MenuScreen_t * const menuScreen);
|
void menu_screen_init(MenuScreen_t * const menuScreen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief Registers a callback functions which will be called every time a user feedback should
|
||||||
|
* be made. In this case, every time a menu item is clicked, the callback will be called.
|
||||||
|
* This enables the app to react to this user event.
|
||||||
*
|
*
|
||||||
* @param menuScreen
|
* @param menuScreen a pointer to the previously initialized menu screen's context structure.
|
||||||
* @param menuScreenOnMenuItemClickCb
|
* @param menuScreenUserFeedbackCb a pointer to a function having the following signature : void(void).
|
||||||
*/
|
*/
|
||||||
void menu_screen_register_on_menu_item_click_cb(MenuScreen_t * const menuScreen, MenuScreenOnMenuItemClickCb_t menuScreenOnMenuItemClickCb);
|
void menu_screen_register_user_feedback_cb(MenuScreen_t * const menuScreen, MenuScreenUserFeedbackCb_t menuScreenUserFeedbackCb);
|
||||||
|
|
||||||
/* Builds the menu screen graphically */
|
/**
|
||||||
|
* @brief Graphically builds the menu screen.
|
||||||
|
*
|
||||||
|
* @param menuScreen a pointer to the previously initialized menu screen's context structure.
|
||||||
|
*/
|
||||||
void menu_screen_create(MenuScreen_t * const menuScreen);
|
void menu_screen_create(MenuScreen_t * const menuScreen);
|
||||||
|
|
||||||
/* Frees all resources used by the MenuScreen object */
|
/**
|
||||||
|
* @brief Frees all resources (GUI and others) used by the MenuScreen_t object.
|
||||||
|
*
|
||||||
|
* @param menuScreen a pointer to the previously initialized menu screen's context structure.
|
||||||
|
*/
|
||||||
void menu_screen_destroy(MenuScreen_t * const menuScreen);
|
void menu_screen_destroy(MenuScreen_t * const menuScreen);
|
||||||
|
|
||||||
#endif //MENU_SCREEN_H
|
#endif //MENU_SCREEN_H
|
||||||
|
Loading…
Reference in New Issue
Block a user