1 /**
2  * @file lv_demo_multilang.c
3  * Recommended resolution 470x640
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "lv_demo_multilang.h"
10 
11 #if LV_USE_DEMO_MULTILANG
12 #include "../../lvgl_private.h"
13 
14 /*********************
15  *      DEFINES
16  *********************/
17 #define CARD_HEIGHT     180
18 
19 /**********************
20  *      TYPEDEFS
21  **********************/
22 typedef struct {
23     const void * image;
24     const char * name;
25     const char * description;
26 } card_info_t;
27 
28 /**********************
29  *  STATIC PROTOTYPES
30  **********************/
31 static void inactive_timer_cb(lv_timer_t * t);
32 static void card_create(lv_obj_t * parent, card_info_t * info);
33 
34 /**********************
35  *  STATIC VARIABLES
36  **********************/
37 static lv_style_t style_card_cont;
38 static lv_style_t style_placeholder;
39 static lv_style_t style_card;
40 static lv_style_t style_avatar;
41 static lv_style_t style_btn;
42 static lv_style_t style_hide;
43 
44 extern lv_font_t font_multilang_small;
45 extern lv_font_t font_multilang_large;
46 
47 /**********************
48  *      MACROS
49  **********************/
50 #define CARD_INFO_SET(_image, _name, _description) {.image = _image, .name = _name, .description = _description}
51 
52 LV_IMAGE_DECLARE(img_multilang_avatar_1);
53 LV_IMAGE_DECLARE(img_multilang_avatar_2);
54 LV_IMAGE_DECLARE(img_multilang_avatar_3);
55 LV_IMAGE_DECLARE(img_multilang_avatar_4);
56 LV_IMAGE_DECLARE(img_multilang_avatar_5);
57 LV_IMAGE_DECLARE(img_multilang_avatar_6);
58 LV_IMAGE_DECLARE(img_multilang_avatar_7);
59 LV_IMAGE_DECLARE(img_multilang_avatar_8);
60 LV_IMAGE_DECLARE(img_multilang_avatar_9);
61 LV_IMAGE_DECLARE(img_multilang_avatar_10);
62 LV_IMAGE_DECLARE(img_multilang_avatar_11);
63 LV_IMAGE_DECLARE(img_multilang_avatar_12);
64 LV_IMAGE_DECLARE(img_multilang_avatar_13);
65 LV_IMAGE_DECLARE(img_multilang_avatar_14);
66 LV_IMAGE_DECLARE(img_multilang_avatar_15);
67 LV_IMAGE_DECLARE(img_multilang_avatar_16);
68 LV_IMAGE_DECLARE(img_multilang_avatar_17);
69 LV_IMAGE_DECLARE(img_multilang_avatar_18);
70 LV_IMAGE_DECLARE(img_multilang_avatar_22);
71 LV_IMAGE_DECLARE(img_multilang_avatar_25);
72 
73 static card_info_t card_info[] = {
74     CARD_INFO_SET(&img_multilang_avatar_5, "Zhang Wei", "对编程和技术充满热情。 开源倡导者��"),
75     CARD_INFO_SET(&img_multilang_avatar_18, "Ali Reza Karami", "عاشق تاریخ و عاشق همه چیز عتیقه. قسمت مورد علاقه من قرن 19 است."),
76     CARD_INFO_SET(&img_multilang_avatar_25, "Sunita Kapoor", "���� हरित कार्यकर्ता, एक स्थायी कल के लिए प्रयासरत। "),
77     CARD_INFO_SET(&img_multilang_avatar_2, "Sofia Bianchi", "Aspirante romanziere con la passione per il caffè e i gatti ��"),
78     CARD_INFO_SET(&img_multilang_avatar_3, "Matthew Parker", "Fitness enthusiast �� Always pushing to reach new goals"),
79     CARD_INFO_SET(&img_multilang_avatar_12, "Shira Cohen", "קורא נלהב שצובר אוסף עצום של ספרים יקרים��"),
80     CARD_INFO_SET(&img_multilang_avatar_7, "Ahmad Al-Masri", "عاشق للأفلام وناقد سينمائي عرضي. معجب بستيفن سبيلبرغ (Steven Spielberg). "),
81     CARD_INFO_SET(&img_multilang_avatar_4, "Ingrid Johansen", "Håpløs romantisk søker etter den spesielle personen ❤️"),
82     CARD_INFO_SET(&img_multilang_avatar_14, "Anastasia Petrova", "Любитель приключений, опытный альпинист."),
83     CARD_INFO_SET(&img_multilang_avatar_6, "Madison Reynolds", "Nature lover and avid hiker ��"),
84     CARD_INFO_SET(&img_multilang_avatar_8, "Pierre Dubois", "Fanatique de sport ⚽ et fan de l'équipe à domicile."),
85     CARD_INFO_SET(&img_multilang_avatar_9, "Benjamin Green", "Dog lover and proud owner of a furry friend ��"),
86     CARD_INFO_SET(&img_multilang_avatar_10, "James Wilson", "Foodie with a passion for trying new restaurants and dishes"),
87     CARD_INFO_SET(&img_multilang_avatar_11, "Olivia Marie Parker", "Gamer at heart, always up for a good round of Mario Kart "),
88     CARD_INFO_SET(&img_multilang_avatar_1, "Ana Garcia Rodriguez", "Viajar por el mundo y probar nuevos alimentos. ��"),
89     CARD_INFO_SET(&img_multilang_avatar_13, "Jamal Brown", "Photographer and amateur astronomer ��"),
90     CARD_INFO_SET(&img_multilang_avatar_15, "Pavel Svoboda", "Hudebník a návštěvník koncertů"),
91     CARD_INFO_SET(&img_multilang_avatar_16, "Elin Lindqvist", "Språkinlärare och kulturentusiast "),
92     CARD_INFO_SET(&img_multilang_avatar_17, "William Carter", "DIY enthusiast and home improvement guru"),
93     CARD_INFO_SET(&img_multilang_avatar_22, "Ava Williams", "Artist and creative visionary ��"),
94     CARD_INFO_SET(NULL, NULL, NULL),
95 };
96 
97 /**********************
98  *   GLOBAL FUNCTIONS
99  **********************/
100 
get_imgfont_path(const lv_font_t * font,uint32_t unicode,uint32_t unicode_next,int32_t * offset_y,void * user_data)101 static const void * get_imgfont_path(const lv_font_t * font,
102                                      uint32_t unicode, uint32_t unicode_next,
103                                      int32_t * offset_y, void * user_data)
104 {
105     LV_UNUSED(user_data);
106     LV_UNUSED(unicode_next);
107     LV_UNUSED(font);
108 
109     LV_IMAGE_DECLARE(img_emoji_artist_palette);
110     LV_IMAGE_DECLARE(img_emoji_books);
111     LV_IMAGE_DECLARE(img_emoji_camera_with_flash);
112     LV_IMAGE_DECLARE(img_emoji_cat_face);
113     LV_IMAGE_DECLARE(img_emoji_deciduous_tree);
114     LV_IMAGE_DECLARE(img_emoji_dog_face);
115     LV_IMAGE_DECLARE(img_emoji_earth_globe_europe_africa);
116     LV_IMAGE_DECLARE(img_emoji_flexed_biceps);
117     LV_IMAGE_DECLARE(img_emoji_movie_camera);
118     LV_IMAGE_DECLARE(img_emoji_red_heart);
119     LV_IMAGE_DECLARE(img_emoji_soccer_ball);
120     LV_IMAGE_DECLARE(img_emoji_rocket);
121 
122     *offset_y = -1;
123     switch(unicode) {
124         case 0x1F30D:
125             return &img_emoji_earth_globe_europe_africa;;
126         case 0x1F431:
127             return &img_emoji_cat_face;
128         case 0x1F4AA:
129             return &img_emoji_flexed_biceps;
130         case 0x2764:
131             return &img_emoji_red_heart;
132         case 0x1F333:
133             return &img_emoji_deciduous_tree;
134         case 0x1F3A5:
135             return &img_emoji_movie_camera;
136         case 0x26BD:
137             return &img_emoji_soccer_ball;
138         case 0x1F436:
139             return &img_emoji_dog_face;
140         case 0x1F4DA:
141             return &img_emoji_books;
142         case 0x1F4F8:
143             return &img_emoji_camera_with_flash;
144         case 0x1F3A8:
145             return &img_emoji_artist_palette;
146         case 0x1F680:
147             return &img_emoji_rocket;
148         default:
149             return NULL;
150     }
151 }
152 
153 lv_font_t * emoji_font;
154 
lv_demo_multilang(void)155 void lv_demo_multilang(void)
156 {
157     emoji_font = lv_imgfont_create(20, get_imgfont_path, NULL);
158     font_multilang_small.fallback = emoji_font;
159 
160     lv_obj_set_flex_flow(lv_screen_active(), LV_FLEX_FLOW_COLUMN);
161     lv_obj_set_style_pad_row(lv_screen_active(), 0, 0);
162     lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0xececec), 0);
163     lv_obj_set_style_bg_grad_color(lv_screen_active(), lv_color_hex(0xf9f9f9), 0);
164     lv_obj_set_style_bg_grad_dir(lv_screen_active(), LV_GRAD_DIR_HOR, 0);
165 
166     static const int32_t grid_cols[] = {LV_GRID_CONTENT, 4, LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
167     static const int32_t grid_rows[] = {LV_GRID_CONTENT, -10, LV_GRID_FR(1), LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
168 
169     lv_style_init(&style_card_cont);
170     lv_style_set_width(&style_card_cont, lv_pct(100));
171     lv_style_set_height(&style_card_cont, CARD_HEIGHT);
172     lv_style_set_layout(&style_card_cont, LV_LAYOUT_FLEX);
173     lv_style_set_flex_flow(&style_card_cont, LV_FLEX_FLOW_ROW);
174     lv_style_set_bg_opa(&style_card_cont, 0);
175     lv_style_set_border_opa(&style_card_cont, 0);
176     lv_style_set_pad_top(&style_card_cont, 5);
177     lv_style_set_pad_bottom(&style_card_cont, 10);
178     lv_style_set_text_font(&style_card_cont, &font_multilang_small);
179 
180     lv_style_init(&style_card);
181     lv_style_set_width(&style_card, lv_pct(100));
182     lv_style_set_height(&style_card, lv_pct(100));
183     lv_style_set_layout(&style_card, LV_LAYOUT_GRID);
184     lv_style_set_grid_column_dsc_array(&style_card, grid_cols);
185     lv_style_set_grid_row_dsc_array(&style_card, grid_rows);
186     lv_style_set_shadow_width(&style_card, 20);
187     lv_style_set_shadow_offset_y(&style_card, 5);
188     lv_style_set_shadow_color(&style_card, lv_color_hex3(0xccc));
189     lv_style_set_border_width(&style_card, 0);
190     lv_style_set_radius(&style_card, 12);
191     lv_style_set_base_dir(&style_card, LV_BASE_DIR_AUTO);
192 
193     lv_style_init(&style_hide);
194     lv_style_set_width(&style_hide, lv_pct(100));
195     lv_style_set_height(&style_hide, lv_pct(100));
196     lv_style_set_bg_color(&style_hide, lv_color_hex(0x759efe));
197     lv_style_set_bg_grad_color(&style_hide, lv_color_hex(0x4173ff));
198     lv_style_set_bg_grad_dir(&style_hide, LV_GRAD_DIR_HOR);
199     lv_style_set_radius(&style_hide, 12);
200     lv_style_set_text_font(&style_hide, &font_multilang_large);
201     lv_style_set_text_color(&style_hide, lv_color_hex(0xffffff));
202 
203     lv_style_init(&style_placeholder);
204     lv_style_set_width(&style_placeholder, lv_pct(100));
205     lv_style_set_height(&style_placeholder, lv_pct(100));
206     lv_style_set_bg_opa(&style_placeholder, 0);
207     lv_style_set_border_opa(&style_placeholder, 0);
208 
209     lv_style_init(&style_avatar);
210     lv_style_set_shadow_width(&style_avatar, 20);
211     lv_style_set_shadow_offset_y(&style_avatar, 5);
212     lv_style_set_shadow_color(&style_avatar, lv_color_hex3(0xbbb));
213     lv_style_set_radius(&style_avatar, LV_RADIUS_CIRCLE);
214 
215     lv_style_init(&style_btn);
216     lv_style_set_width(&style_btn, 160);
217     lv_style_set_height(&style_btn, 37);
218     lv_style_set_bg_color(&style_btn, lv_color_hex(0x759efe));
219     lv_style_set_bg_grad_color(&style_btn, lv_color_hex(0x4173ff));
220     lv_style_set_bg_grad_dir(&style_btn, LV_GRAD_DIR_HOR);
221     lv_style_set_radius(&style_btn, LV_RADIUS_CIRCLE);
222     lv_style_set_shadow_width(&style_btn, 0);
223 
224     uint32_t i;
225     for(i = 0; card_info[i].image; i++) {
226         card_create(lv_screen_active(), &card_info[i]);
227     }
228 
229     lv_timer_create(inactive_timer_cb, 1000, NULL);
230 }
231 
232 /**********************
233  *   STATIC FUNCTIONS
234  **********************/
235 
inactive_timer_cb(lv_timer_t * t)236 static void inactive_timer_cb(lv_timer_t * t)
237 {
238     LV_UNUSED(t);
239 
240     static bool scrolled = false;
241     lv_obj_t * cont = lv_obj_get_child(lv_screen_active(), 0);
242     if(cont == NULL) return;
243 
244     if(scrolled) {
245         lv_obj_scroll_by(cont, -100, 0, LV_ANIM_ON);
246         lv_obj_remove_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE);
247         scrolled = false;
248         return;
249     }
250 
251     if(lv_display_get_inactive_time(NULL) > 8000) {
252         lv_display_trigger_activity(NULL);
253         lv_obj_scroll_by(cont, 100, 0, LV_ANIM_ON);
254         lv_obj_add_flag(lv_layer_top(), LV_OBJ_FLAG_CLICKABLE);
255         scrolled = true;
256     }
257 }
258 
shrink_anim_cb(void * var,int32_t v)259 static void shrink_anim_cb(void * var, int32_t v)
260 {
261     lv_obj_t * cont = var;
262     lv_obj_set_height(cont, (v * CARD_HEIGHT) >> 8);
263     lv_obj_set_style_opa(cont, v, 0);
264 }
265 
scroll_event_cb(lv_event_t * e)266 static void scroll_event_cb(lv_event_t * e)
267 {
268     lv_indev_t * indev = lv_indev_active();
269     lv_obj_t * cont = lv_event_get_target(e);
270     if(lv_indev_get_scroll_obj(indev) != cont) return;
271 
272     int32_t w = lv_obj_get_width(cont);
273     int32_t scroll_x = lv_obj_get_scroll_x(cont) - lv_indev_scroll_throw_predict(indev, LV_DIR_HOR);
274 
275     if(scroll_x < w / 2) {
276         lv_obj_set_scroll_snap_x(cont, LV_SCROLL_SNAP_NONE);
277         lv_obj_remove_flag(cont, LV_OBJ_FLAG_CLICKABLE);
278         lv_indev_wait_release(indev);
279         lv_obj_scroll_to_view(lv_obj_get_child(cont, 0), LV_ANIM_ON);
280 
281         lv_anim_t a;
282         lv_anim_init(&a);
283         lv_anim_set_exec_cb(&a, shrink_anim_cb);
284         lv_anim_set_completed_cb(&a, lv_obj_delete_anim_completed_cb);
285         lv_anim_set_values(&a, 255, 0);
286         lv_anim_set_duration(&a, 400);
287         lv_anim_set_var(&a, cont);
288         lv_anim_start(&a);
289     }
290 }
291 
card_create(lv_obj_t * parent,card_info_t * info)292 static void card_create(lv_obj_t * parent, card_info_t * info)
293 {
294     lv_obj_t * cont = lv_obj_create(parent);
295     lv_obj_add_style(cont, &style_card_cont, 0);
296     lv_obj_set_scroll_snap_x(cont, LV_SCROLL_SNAP_CENTER);
297     lv_obj_add_event_cb(cont, scroll_event_cb, LV_EVENT_RELEASED, NULL);
298     lv_obj_remove_flag(cont, LV_OBJ_FLAG_SCROLL_ELASTIC);
299     lv_obj_set_scrollbar_mode(cont, LV_SCROLLBAR_MODE_OFF);
300 
301     lv_obj_t * remove = lv_obj_create(cont);
302     lv_obj_add_style(remove, &style_hide, 0);
303     lv_obj_remove_flag(remove, LV_OBJ_FLAG_SNAPPABLE);
304     lv_obj_add_flag(remove, LV_OBJ_FLAG_FLOATING);
305     lv_obj_remove_flag(remove, LV_OBJ_FLAG_CLICKABLE);
306 
307     lv_obj_t * hide_label = lv_label_create(remove);
308     lv_label_set_text(hide_label, "Hide");
309     lv_obj_align(hide_label, LV_ALIGN_LEFT_MID, 10, 0);
310 
311     lv_obj_t * placeholder = lv_obj_create(cont);
312     lv_obj_add_style(placeholder, &style_placeholder, 0);
313 
314     lv_obj_t * card = lv_obj_create(cont);
315     lv_obj_add_style(card, &style_card, 0);
316     lv_obj_remove_flag(card, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_SCROLLABLE | LV_OBJ_FLAG_SCROLL_CHAIN_HOR);
317 
318     lv_obj_t * avatar = lv_image_create(card);
319     lv_image_set_src(avatar, info->image);
320     lv_obj_set_grid_cell(avatar, LV_GRID_ALIGN_CENTER, 0, 1, LV_GRID_ALIGN_CENTER, 0, 4);
321     lv_obj_add_style(avatar, &style_avatar, 0);
322 
323     lv_obj_t * name = lv_label_create(card);
324     lv_label_set_text(name, info->name);
325     lv_obj_set_grid_cell(name, LV_GRID_ALIGN_START, 2, 1, LV_GRID_ALIGN_CENTER, 0, 1);
326     lv_obj_set_style_text_font(name, &font_multilang_large, 0);
327 
328     lv_obj_t * description = lv_label_create(card);
329     lv_label_set_text(description, info->description);
330     lv_obj_set_grid_cell(description, LV_GRID_ALIGN_STRETCH, 2, 1, LV_GRID_ALIGN_STRETCH, 2, 1);
331     lv_obj_set_style_text_color(description, lv_color_hex(0x5b5b5b), 0);
332     lv_obj_set_style_text_line_space(description, -3, 0);
333 
334     lv_obj_t * btn = lv_button_create(card);
335     lv_obj_remove_flag(card, LV_OBJ_FLAG_SCROLL_CHAIN_HOR);
336     lv_obj_set_grid_cell(btn, LV_GRID_ALIGN_START, 2, 1, LV_GRID_ALIGN_CENTER, 3, 1);
337     lv_obj_add_style(btn, &style_btn, 0);
338 
339     LV_IMAGE_DECLARE(img_multilang_like);
340     lv_obj_t * btn_img = lv_image_create(btn);
341     lv_image_set_src(btn_img, &img_multilang_like);
342     lv_obj_align(btn_img, LV_ALIGN_LEFT_MID, 30, 0);
343 
344     lv_obj_t * btn_label = lv_label_create(btn);
345     lv_label_set_text(btn_label, "Like");
346     lv_obj_align(btn_label, LV_ALIGN_LEFT_MID, 60, 1);
347 
348     lv_obj_scroll_to_view(card, LV_ANIM_OFF);
349 }
350 
351 #endif
352