Skip to content

Commit ffa70a6

Browse files
feat: implement flex layout to reduce absoluteness
Within this commit, we preserve the same style on home screen but use flexbox patterns in LVGL. To help the further development better, we introduce a new interface called display/utils.h to enable developers to create their flexbox views easily.
1 parent 09a8b38 commit ffa70a6

File tree

4 files changed

+138
-42
lines changed

4 files changed

+138
-42
lines changed

src/display/screens/home/home.c

Lines changed: 22 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "lvgl.h"
22
#include "display/display.h"
3+
#include "display/utils.h"
34

45
// Holds the home screen object.
56
lv_obj_t *home_screen;
@@ -9,14 +10,22 @@ lv_obj_t *label_day;
910

1011
void home_screen_init() {
1112
// Create the screen object which is the LV object with no parent.
12-
home_screen = lv_obj_create(NULL);
13-
// Remove the ability to scroll the screen.
14-
lv_obj_remove_flag(home_screen, LV_OBJ_FLAG_SCROLLABLE);
13+
home_screen = create_screen();
14+
15+
// Create a vertical flex layout container centered in the screen.
16+
lv_obj_t *main_column = create_column(home_screen, 100, 100);
17+
18+
// Create a horizontal flex layout containers that will hold date and time labels.
19+
lv_obj_t *clock_label_row = create_row(main_column, 100, 20);
20+
lv_obj_t *date_day_row = create_row(main_column, 100, 20);
21+
22+
// Add spacing between rows.
23+
lv_obj_set_style_pad_row(main_column, 5, LV_PART_MAIN);
1524

1625
// Render items in the screen.
17-
render_clock_label();
18-
render_date_label();
19-
render_day_label();
26+
render_clock_label(clock_label_row);
27+
render_date_label(date_day_row);
28+
render_day_label(date_day_row);
2029

2130
// Add an event handler for all possible events.
2231
lv_obj_add_event_cb(home_screen, home_screen_event, LV_EVENT_ALL, NULL);
@@ -26,53 +35,27 @@ void home_screen_event(lv_event_t * e) {
2635
// lv_event_code_t event_code = lv_event_get_code(e);lv_obj_t * target = lv_event_get_target(e);
2736
}
2837

29-
void render_clock_label() {
30-
// Create a new label and expand its size to content size and align it to center.
31-
label_clock = lv_label_create(home_screen);
38+
void render_clock_label(lv_obj_t *flex_element) {
39+
label_clock = lv_label_create(flex_element);
3240
lv_obj_set_width(label_clock, LV_SIZE_CONTENT);
3341
lv_obj_set_height(label_clock, LV_SIZE_CONTENT);
34-
lv_obj_set_align(label_clock, LV_ALIGN_CENTER);
35-
36-
// Align to center but with upward Y offset.
37-
lv_obj_align(label_clock, LV_ALIGN_CENTER, 0, -20);
38-
39-
// Set the default text.
4042
lv_label_set_text(label_clock, "HH:mm");
4143

42-
// Format the clock text string.
43-
/* 1. Set the letter spacing to 5. (Between letters)
44-
* 2. Set the line spacing to 0. (Between new lines)
45-
* 3. Align the text automatically.
46-
* 4. Set no decoration on the text.
47-
* 5. Set the font and the size to Montserrat 46.
48-
*/
4944
lv_obj_set_style_text_letter_space(label_clock, 5, LV_PART_MAIN | LV_STATE_DEFAULT);
5045
lv_obj_set_style_text_line_space(label_clock, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
51-
lv_obj_set_style_text_align(label_clock, LV_TEXT_ALIGN_AUTO, LV_PART_MAIN | LV_STATE_DEFAULT);
46+
lv_obj_set_style_text_align(label_clock, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT);
5247
lv_obj_set_style_text_decor(label_clock, LV_TEXT_DECOR_NONE, LV_PART_MAIN | LV_STATE_DEFAULT);
5348
lv_obj_set_style_text_font(label_clock, &lv_font_montserrat_46, LV_PART_MAIN | LV_STATE_DEFAULT);
5449
}
5550

56-
void render_date_label() {
57-
// Create a new label and expand its size to content size and align it to center.
58-
label_date = lv_label_create(home_screen);
59-
60-
// Align it to the bottom of the clock label with a margin of 2x5y pixels.
61-
lv_obj_align_to(label_date, label_clock, LV_ALIGN_OUT_BOTTOM_MID, -65, 0);
62-
63-
// Set the default text.
51+
void render_date_label(lv_obj_t *flex_element) {
52+
label_date = lv_label_create(flex_element);
6453
lv_label_set_text(label_date, "YYYY-MM-DD");
6554
lv_obj_set_style_text_font(label_date, &lv_font_montserrat_18, LV_PART_MAIN | LV_STATE_DEFAULT);
6655
}
6756

68-
void render_day_label() {
69-
// Create a new label and expand its size to content size and align it to center.
70-
label_day = lv_label_create(home_screen);
71-
72-
// Align it to the bottom of the clock label with a margin of 2x5y pixels.
73-
lv_obj_align_to(label_day, label_clock, LV_ALIGN_OUT_BOTTOM_MID, +45, 0);
74-
75-
// Set the default text.
57+
void render_day_label(lv_obj_t *flex_element) {
58+
label_day = lv_label_create(flex_element);
7659
lv_label_set_text(label_day, "DAY");
7760
lv_obj_set_style_text_font(label_day, &lv_font_montserrat_18, LV_PART_MAIN | LV_STATE_DEFAULT);
7861
}

src/display/screens/home/home.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ void home_screen_init();
1515
void home_screen_event(lv_event_t * e);
1616

1717
// Render labels.
18-
void render_clock_label();
19-
void render_date_label();
20-
void render_day_label();
18+
void render_clock_label(lv_obj_t *flex_element);
19+
void render_date_label(lv_obj_t *flex_element);
20+
void render_day_label(lv_obj_t *flex_element);
2121

2222
// Set the values on the home-screen. Returns 0 if successful, 1 otherwise.
2323
uint8_t home_screen_set_clock(uint8_t hour, uint8_t minute);

src/display/utils.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#include "lvgl.h"
2+
3+
void remove_scrollable(lv_obj_t *obj) {
4+
// Remove the ability to scroll the object.
5+
lv_obj_remove_flag(obj, LV_OBJ_FLAG_SCROLLABLE);
6+
lv_obj_remove_flag(obj, LV_OBJ_FLAG_SCROLL_CHAIN);
7+
// Set the scrollbar mode of the object to off.
8+
lv_obj_set_scrollbar_mode(obj, LV_SCROLLBAR_MODE_OFF);
9+
}
10+
11+
lv_obj_t* create_screen() {
12+
// Create the screen object which is the LV object with no parent.
13+
lv_obj_t *screen = lv_obj_create(NULL);
14+
remove_scrollable(screen);
15+
return screen;
16+
}
17+
18+
lv_obj_t* create_column(lv_obj_t* root, uint8_t width_perc, uint8_t height_perc) {
19+
// Check the parameters if null. If so, set them 100.
20+
if (!width_perc) width_perc = 100;
21+
if (!height_perc) height_perc = 100;
22+
23+
// Create a vertical flex layout container centered in the screen.
24+
lv_obj_t *column = lv_obj_create(root);
25+
lv_obj_set_size(column, LV_PCT(width_perc), LV_PCT(height_perc));
26+
lv_obj_center(column);
27+
28+
// Set the layout.
29+
lv_obj_set_layout(column, LV_LAYOUT_FLEX);
30+
lv_obj_set_flex_flow(column, LV_FLEX_FLOW_COLUMN);
31+
lv_obj_set_flex_align(column,
32+
LV_FLEX_ALIGN_CENTER, // Main axis (vertical)
33+
LV_FLEX_ALIGN_CENTER, // Cross axis (horizontal)
34+
LV_FLEX_ALIGN_CENTER); // Track alignment
35+
36+
// Remove scrolling and set it to off.
37+
remove_scrollable(column);
38+
39+
// Remove the borders.
40+
lv_obj_set_style_border_width(column, 0, LV_PART_MAIN);
41+
lv_obj_set_style_bg_opa(column, LV_OPA_TRANSP, LV_PART_MAIN);
42+
43+
// Return the column instance.
44+
return column;
45+
}
46+
47+
lv_obj_t* create_row(lv_obj_t* root, uint8_t width_perc, uint8_t height_perc) {
48+
// Check the parameters if null. If so, set them 100.
49+
if (!width_perc) width_perc = 100;
50+
if (!height_perc) height_perc = 100;
51+
52+
// Create a new row object inside the root.
53+
lv_obj_t *row = lv_obj_create(root);
54+
lv_obj_set_size(row, LV_PCT(width_perc), LV_PCT(height_perc));
55+
lv_obj_center(row);
56+
57+
// Use flext layout on the row.
58+
lv_obj_set_layout(row, LV_LAYOUT_FLEX);
59+
lv_obj_set_flex_flow(row, LV_FLEX_FLOW_ROW);
60+
lv_obj_set_flex_align(row,
61+
LV_FLEX_ALIGN_CENTER, // Main axis (vertical)
62+
LV_FLEX_ALIGN_CENTER, // Cross axis (horizontal)
63+
LV_FLEX_ALIGN_CENTER); // Track alignment
64+
65+
// Remove scrolling and set it to off.
66+
remove_scrollable(row);
67+
68+
// Remove the borders.
69+
lv_obj_set_style_border_width(row, 0, LV_PART_MAIN);
70+
lv_obj_set_style_bg_opa(row, LV_OPA_TRANSP, LV_PART_MAIN);
71+
72+
// Return the created row object.
73+
return row;
74+
}

src/display/utils.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#ifndef _DISPLAY_UTILS_H
2+
#define _DISPLAY_UTILS_H
3+
4+
#ifdef __cplusplus
5+
extern "C" {
6+
#endif
7+
8+
#include "lvgl.h"
9+
10+
/**
11+
* Create a new screen object with no parent and scrolling.
12+
* @return The created lv_obj_t screen instance.
13+
*/
14+
lv_obj_t* create_screen();
15+
16+
/**
17+
* Create a new flex column object inside the root.
18+
* @param root The parent of the created lv_obj_t column instance.
19+
* @param width_perc The percentage of the screen width to use for this column.
20+
* @param height_perc The percentage of the screen height to use for this column.
21+
* @return The created lv_obj_t column instance.
22+
*/
23+
lv_obj_t* create_column(lv_obj_t* root, uint8_t width_perc, uint8_t height_perc);
24+
25+
/**
26+
* Create a new flex row object inside the root.
27+
* @param root The parent of the created lv_obj_t row instance.
28+
* @param width_perc The percentage of the screen width to use for this row.
29+
* @param height_perc The percentage of the screen height to use for this row.
30+
* @return The created lv_obj_t row instance.
31+
*/
32+
lv_obj_t* create_row(lv_obj_t* root, uint8_t width_perc, uint8_t height_perc);
33+
34+
35+
#ifdef __cplusplus
36+
}
37+
#endif
38+
39+
#endif // _DISPLAY_UTILS_H

0 commit comments

Comments
 (0)