1 /**
2  * @file lv_demo_smartwatch_qr.c
3  * QR code screen layout & functions. Contains QR code for quick access to items such as contact cards etc.
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "lv_demo_smartwatch.h"
10 #if LV_USE_DEMO_SMARTWATCH
11 
12 #include <string.h>
13 #include "lv_demo_smartwatch_private.h"
14 #include "lv_demo_smartwatch_qr.h"
15 
16 /*********************
17  *      DEFINES
18  *********************/
19 
20 /**********************
21  *      TYPEDEFS
22  **********************/
23 
24 /**********************
25  *  STATIC PROTOTYPES
26  **********************/
27 static void qr_screen_create(void);
28 static void qr_screen_event_cb(lv_event_t * e);
29 
30 /**********************
31  *  STATIC VARIABLES
32  **********************/
33 
34 static lv_obj_t * qr_screen;
35 static lv_obj_t * qr_panel;
36 static lv_obj_t * qr_item;
37 static lv_obj_t * qr_icon;
38 static lv_obj_t * qr_image;
39 static lv_obj_t * qr_label;
40 
41 static const lv_image_dsc_t * qr_image_icons[] = {
42     &img_chrns_icon,
43     &img_wechat_icon,
44     &img_facebook_icon,
45     &img_penguin_icon,
46     &img_twitter_x_icon,
47     &img_whatsapp_icon,
48     &img_wechat_pay_icon, /* wechat pay */
49     &img_alipay_icon,     /* alipay */
50     &img_paypal_icon,     /* paypal */
51 };
52 
53 const char * qr_title_names[9] = {
54     "Chronos",
55     "Wechat",
56     "Facebook",
57     "QQ",
58     "X (Twitter)",
59     "Whatsapp",
60     "Wechat Pay",
61     "Alipay",
62     "Paypal"
63 };
64 
65 /**********************
66  *      MACROS
67  **********************/
68 
69 /**********************
70  *   GLOBAL FUNCTIONS
71  **********************/
72 
lv_demo_smartwatch_qr_create(void)73 void lv_demo_smartwatch_qr_create(void)
74 {
75     qr_screen_create();
76 
77 #if LV_USE_QRCODE == 1
78 
79     lv_demo_smartwatch_qr_list_add(0, "https://chronos.ke/");
80     lv_demo_smartwatch_qr_list_add(1, "https://www.youtube.com/c/fbiego");
81     lv_demo_smartwatch_qr_list_add(2, "https://play.google.com/store/apps/details?id=com.fbiego.chronos");
82     lv_demo_smartwatch_qr_list_add(3, "https://github.com/fbiego/esp32-c3-mini");
83     lv_demo_smartwatch_qr_list_add(4, "https://x.com/chronos_app");
84     lv_demo_smartwatch_qr_list_add(5, "https://felix.fbiego.com");
85     lv_demo_smartwatch_qr_list_add(6, "https://www.linkedin.com/in/fbiego/");
86     lv_demo_smartwatch_qr_list_add(7, "https://ko-fi.com/fbiego");
87     lv_demo_smartwatch_qr_list_add(8, "https://www.paypal.com/paypalme/biego");
88 
89 #else
90     LV_LOG_WARN("QR Code feature not enabled");
91 
92     lv_obj_t * info = lv_label_create(qr_panel);
93     lv_obj_set_width(info, lv_pct(75));
94     lv_obj_set_height(info, LV_SIZE_CONTENT);
95     lv_obj_set_align(info, LV_ALIGN_CENTER);
96     lv_label_set_text(info, "QR feature is not enabled. Enable it in lv_conf.h (LV_USE_QRCODE 1)");
97 
98 #endif /*LV_USE_QRCODE*/
99 }
100 
lv_demo_smartwatch_qr_load(lv_screen_load_anim_t anim_type,uint32_t time,uint32_t delay)101 void lv_demo_smartwatch_qr_load(lv_screen_load_anim_t anim_type, uint32_t time, uint32_t delay)
102 {
103     lv_screen_load_anim(qr_screen, anim_type, time, delay, false);
104 }
105 
lv_demo_smartwatch_qr_list_clear(void)106 void lv_demo_smartwatch_qr_list_clear(void)
107 {
108     lv_obj_clean(qr_panel);
109 }
110 
lv_demo_smartwatch_qr_list_add(uint8_t id,const char * link)111 void lv_demo_smartwatch_qr_list_add(uint8_t id, const char * link)
112 {
113 #if LV_USE_QRCODE == 1
114     qr_item = lv_obj_create(qr_panel);
115     lv_obj_set_width(qr_item, lv_pct(85));
116     lv_obj_set_height(qr_item, lv_pct(100));
117     lv_obj_set_align(qr_item, LV_ALIGN_CENTER);
118     lv_obj_set_flex_flow(qr_item, LV_FLEX_FLOW_COLUMN);
119     lv_obj_set_flex_align(qr_item, LV_FLEX_ALIGN_SPACE_BETWEEN, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
120     lv_obj_remove_flag(qr_item, LV_OBJ_FLAG_SCROLLABLE);
121     lv_obj_add_flag(qr_item, LV_OBJ_FLAG_SNAPPABLE);
122     lv_obj_remove_flag(qr_item, LV_OBJ_FLAG_SCROLL_ONE);
123     lv_obj_set_style_bg_color(qr_item, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT);
124     lv_obj_set_style_bg_opa(qr_item, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
125     lv_obj_set_style_border_width(qr_item, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
126 
127     qr_icon = lv_image_create(qr_item);
128     lv_image_set_src(qr_icon, qr_image_icons[id % 9]);
129     lv_obj_set_width(qr_icon, LV_SIZE_CONTENT);
130     lv_obj_set_height(qr_icon, LV_SIZE_CONTENT);
131     lv_obj_set_align(qr_icon, LV_ALIGN_CENTER);
132     lv_obj_add_flag(qr_icon, LV_OBJ_FLAG_ADV_HITTEST);
133     lv_obj_remove_flag(qr_icon, LV_OBJ_FLAG_SCROLLABLE);
134 
135     qr_image = lv_qrcode_create(qr_item);
136     lv_qrcode_set_size(qr_image, 150);
137     lv_qrcode_set_dark_color(qr_image, lv_color_black());
138     lv_qrcode_set_light_color(qr_image, lv_color_white());
139     lv_qrcode_update(qr_image, link, strlen(link));
140     lv_obj_center(qr_image);
141     lv_obj_set_style_border_color(qr_image, lv_color_hex(0xFFFFFF), 0);
142     lv_obj_set_style_border_width(qr_image, 5, 0);
143     lv_obj_set_align(qr_image, LV_ALIGN_CENTER);
144     lv_obj_remove_flag(qr_image, LV_OBJ_FLAG_SCROLLABLE);
145     lv_obj_set_style_bg_color(qr_image, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT);
146     lv_obj_set_style_bg_opa(qr_image, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
147 
148     qr_label = lv_label_create(qr_item);
149     lv_obj_set_width(qr_label, LV_SIZE_CONTENT);
150     lv_obj_set_height(qr_label, LV_SIZE_CONTENT);
151     lv_obj_set_align(qr_label, LV_ALIGN_CENTER);
152     lv_label_set_text(qr_label, qr_title_names[id % 9]);
153     lv_obj_set_style_text_font(qr_label, &lv_font_montserrat_14, LV_PART_MAIN | LV_STATE_DEFAULT);
154 #else
155     LV_LOG_WARN("QR Code not added, feature is not enabled");
156 #endif /*LV_USE_QRCODE*/
157 }
158 
159 /**********************
160  *   STATIC FUNCTIONS
161  **********************/
qr_screen_create(void)162 static void qr_screen_create(void)
163 {
164     qr_screen = lv_obj_create(NULL);
165     lv_obj_remove_flag(qr_screen, LV_OBJ_FLAG_SCROLLABLE);
166 
167     qr_panel = lv_obj_create(qr_screen);
168     lv_obj_set_width(qr_panel, lv_pct(100));
169     lv_obj_set_height(qr_panel, lv_pct(100));
170     lv_obj_set_align(qr_panel, LV_ALIGN_CENTER);
171     lv_obj_set_flex_flow(qr_panel, LV_FLEX_FLOW_ROW);
172     lv_obj_set_flex_align(qr_panel, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_START);
173     lv_obj_add_flag(qr_panel, LV_OBJ_FLAG_SCROLL_ONE);
174     lv_obj_set_scrollbar_mode(qr_panel, LV_SCROLLBAR_MODE_OFF);
175     lv_obj_set_scroll_snap_x(qr_panel, LV_SCROLL_SNAP_CENTER);
176     lv_obj_set_scroll_dir(qr_panel, LV_DIR_HOR);
177     lv_obj_set_style_radius(qr_panel, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
178     lv_obj_set_style_bg_color(qr_panel, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT);
179     lv_obj_set_style_bg_opa(qr_panel, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
180     lv_obj_set_style_border_width(qr_panel, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
181     lv_obj_set_style_pad_left(qr_panel, 20, LV_PART_MAIN | LV_STATE_DEFAULT);
182     lv_obj_set_style_pad_right(qr_panel, 20, LV_PART_MAIN | LV_STATE_DEFAULT);
183     lv_obj_set_style_pad_top(qr_panel, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
184     lv_obj_set_style_pad_bottom(qr_panel, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
185 
186     lv_obj_add_event_cb(qr_screen, qr_screen_event_cb, LV_EVENT_ALL, NULL);
187 }
188 
qr_screen_event_cb(lv_event_t * e)189 static void qr_screen_event_cb(lv_event_t * e)
190 {
191     lv_event_code_t event_code = lv_event_get_code(e);
192 
193     if(event_code == LV_EVENT_GESTURE && lv_indev_get_gesture_dir(lv_indev_active()) == LV_DIR_TOP) {
194         if(lv_demo_smartwatch_get_load_app_list()) {
195             lv_demo_smartwatch_home_load(LV_SCR_LOAD_ANIM_MOVE_TOP, 500, 0);
196         }
197         else {
198             lv_demo_smartwatch_home_load(LV_SCR_LOAD_ANIM_MOVE_TOP, 500, 0);
199         }
200     }
201 
202     if(event_code == LV_EVENT_GESTURE && lv_indev_get_gesture_dir(lv_indev_active()) == LV_DIR_BOTTOM) {
203         lv_demo_smartwatch_show_scroll_hint(LV_DIR_BOTTOM);
204     }
205 
206     if(event_code == LV_EVENT_SCREEN_LOAD_START) {
207         lv_obj_set_scrollbar_mode(qr_panel, lv_demo_smartwatch_get_scrollbar_mode());
208 
209         lv_obj_update_snap(qr_panel, LV_ANIM_OFF);
210 
211         lv_demo_smartwatch_show_scroll_hint(LV_DIR_BOTTOM);
212 
213     }
214 }
215 
216 #endif /*LV_USE_DEMO_SMARTWATCH*/
217