Skip to content

Commit 15032ed

Browse files
author
LanFly
committedJul 26, 2022
feat: 完整支持页面滑动动画
1 parent 57bba5b commit 15032ed

File tree

5 files changed

+197
-47
lines changed

5 files changed

+197
-47
lines changed
 

‎README-en.md

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# LVGL-PM
2+
3+
![version v0.1.1](https://img.shields.io/badge/version-v0.1.1-brightgreen)
4+
![license MIT](https://img.shields.io/badge/license-MIT-green)
5+
6+
**[【中文文档】](./README.md)**
7+
8+
A simple page manager for LVGL.
9+
10+
## Features
11+
12+
simple and easy to use.
13+
14+
- Page lifecycle management
15+
- Support transition animation
16+
17+
## Example
18+
19+
```c
20+
#include "pm.h"
21+
22+
void main()
23+
{
24+
lv_pm_init();
25+
26+
lv_pm_page_t *home = lv_pm_create_page(0);
27+
page->onLoad = page_home_onLoad; // you should implement this function
28+
page->unLoad = page_home_unLoad; // you should implement this function
29+
30+
lv_pm_open_page(0, NULL);
31+
}
32+
```
33+
34+
## Write a page
35+
36+
```c
37+
// home.c
38+
39+
#include "home.h"
40+
41+
void page_home_onLoad(lv_obj_t *page)
42+
{
43+
lv_obj_t *label = lv_label_create(page);
44+
lv_label_set_text(label, "hello home page");
45+
}
46+
47+
void page_home_unLoad(lv_obj_t *page)
48+
{
49+
// all children of page will be deleted automatically.
50+
}
51+
```
52+
53+
## API
54+
55+
**uint8_t lv_pm_init()**
56+
57+
This function muse be called before using LVGL-PM.
58+
59+
return 0 is OK.
60+
61+
**lv_pm_page_t \*lv_pm_create_page(uint8_t id)**
62+
63+
Create a page and specify an ID. The ID is used for lv_pm_open_page API.
64+
65+
There are 2 lifecycle that must be registered:
66+
67+
1. onLoad
68+
2. unLoad
69+
70+
**uint8_t lv_pm_open_page(uint8_t id, lv_pm_open_options_t \*behavior)**
71+
72+
Open the page according to the specified ID.
73+
74+
> Warning: A specified page ID can only be opened once at time. In the future version, we will support multi page instances.
75+
76+
**uint8_t lv_pm_back()**
77+
78+
Close the current page and display the previous page. Do nothing if there is only one page or nothing.
79+
80+
## Lifecycle
81+
82+
1. onLoad
83+
2. willAppear
84+
3. didAppear
85+
4. willDisappear
86+
5. didDisappear
87+
6. unLoad
88+
89+
## buildin animation
90+
91+
- LV_PM_ANIMA_NONE (support)
92+
- LV_PM_ANIMA_SLIDE (support)
93+
- LV_PM_ANIMA_SLIDE_SCALE (not yet)

‎README.md

+57-29
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
# LVGL-PM
22

3-
**【中文文档】马上来**
3+
![version v0.1.1](https://img.shields.io/badge/version-v0.1.1-brightgreen)
4+
![license MIT](https://img.shields.io/badge/license-MIT-green)
45

5-
A simple page manager for LVGL.
6+
**[English Document](./README-en.md)**
67

7-
## Features
8+
一个为 LVGL 精心定制的 APP 页面管理器,简单易用,功能强大,支持多种酷炫动画
89

9-
simple and easy to use.
10+
## 特性
1011

11-
- Page lifecycle management
12-
- Support transition animation
12+
简单、易用、强大
1313

14-
## Example
14+
- 支持页面全生命周期管理,参考手机 APP 生命周期
15+
- 支持多种酷炫动画,内置集成
16+
- 多个页面代码隔离,单文件开发体验
17+
18+
## 使用示例
1519

1620
```c
1721
#include "pm.h"
@@ -21,14 +25,14 @@ void main()
2125
lv_pm_init();
2226

2327
lv_pm_page_t *home = lv_pm_create_page(0);
24-
page->onLoad = page_home_onLoad; // you should implement this function
25-
page->unLoad = page_home_unLoad; // you should implement this function
28+
page->onLoad = page_home_onLoad; // 需要你实现的页面函数
29+
page->unLoad = page_home_unLoad; // 需要你实现的页面函数
2630

2731
lv_pm_open_page(0, NULL);
2832
}
2933
```
3034

31-
## Write a page
35+
## 编写页面
3236

3337
```c
3438
// home.c
@@ -37,54 +41,78 @@ void main()
3741

3842
void page_home_onLoad(lv_obj_t *page)
3943
{
44+
// 所有对象都挂载在 page 下面,页面管理器会自动帮你管理内存
4045
lv_obj_t *label = lv_label_create(page);
4146
lv_label_set_text(label, "hello home page");
4247
}
4348

4449
void page_home_unLoad(lv_obj_t *page)
4550
{
46-
// all children of page will be deleted automatically.
51+
// onLoad 和 unLoad 必须实现,所有挂载在 page 下的对象都会自动释放
52+
// 你只需要释放自己申请的内存
4753
}
4854
```
4955
5056
## API
5157
5258
**uint8_t lv_pm_init()**
5359
54-
This function muse be called before using LVGL-PM.
60+
这个函数必须在使用任何页面管理器 API 之前调用
5561
56-
return 0 is OK.
62+
返回 0 表示 OK,其它值表示错误,你需要自己处理错误
5763
5864
**lv_pm_page_t \*lv_pm_create_page(uint8_t id)**
5965
60-
Create a page and specify an ID. The ID is used for lv_pm_open_page API.
66+
创建一个路由并且指定路由标识 ID,这个 ID 在打开页面时会用到,必须唯一。
67+
68+
一般 ID 从下标 0 开始,你可以按照页面的顺序来分配 ID
69+
70+
> 注意:默认路由表长度是 10,所以你不能使用超过长度的 ID 值,如果大于 10,你可以使用 `#define LV_PM_PAGE_NUM 20` 指定长度
6171
62-
There are 2 lifecycle that must be registered:
72+
创建好路由后,你可以注册页面的生命周期函数了,此时并不会真正的创建页面
73+
74+
下面 2 个生命周期是必须实现的:
6375
6476
1. onLoad
6577
2. unLoad
6678
6779
**uint8_t lv_pm_open_page(uint8_t id, lv_pm_open_options_t \*behavior)**
6880
69-
Open the page according to the specified ID.
81+
根据指定的路由 ID 打开页面,此时会调用 onLoad 真正创建页面
82+
83+
参数 `behavior`:指定打开页面的行为,过渡动画,打开方式,动画方向。默认为 `NULL`
84+
85+
> 注意:为了页面代码简单,我们并没有实现多实例。所以一个路由 ID 同时只能被打开一次,打开 2 次以上的行为是未定义的,会产生不可预期的错误
86+
> 在未来的版本中,我们会支持页面多实例
7087
71-
> Warning: A specified page ID can only be opened once at time. In the future version, we will support multi page instances.
88+
示例:
89+
```c
90+
#include "pm.h"
91+
92+
lv_pm_open_options_t options = {
93+
.animation = LV_PM_ANIMA_SLIDE // 使用滑动动画打开页面
94+
};
95+
96+
lv_pm_open_page(0, &options);
97+
// 或者使用默认行为 lv_pm_open_page(0, NULL);
98+
```
7299

73100
**uint8_t lv_pm_back()**
74101

75-
Close the current page and display the previous page. Do nothing if there is only one page or nothing.
102+
关闭当前页面并且显示上一个页面。如果当前只有一个页面或者没有打开页面,则此函数什么也不做
76103

77-
## Lifecycle
104+
## 完整的生命周期
78105

79-
1. onLoad
80-
2. willAppear
81-
3. didAppear
82-
4. willDisappear
83-
5. didDisappear
84-
6. unLoad
106+
1. onLoad : 页面创建,你可以在这里执行初始化
107+
2. willAppear : 页面即将被展示
108+
3. didAppear : 页面已经被完整展示
109+
4. willDisappear : 页面即将被隐藏
110+
5. didDisappear : 页面已经被隐藏不可见
111+
6. unLoad : 页面被关闭,你需要在这里释放所有临时内存,否则可能存在泄漏
85112

86-
## buildin animation
113+
## 内置过渡动画
87114

88-
- LV_PM_ANIMA_NONE (support)
89-
- LV_PM_ANIMA_SLIDE (support)
90-
- LV_PM_ANIMA_SLIDE_SCALE (not yet)
115+
- [x] LV_PM_ANIMA_NONE: 不使用过渡动画
116+
- [x] LV_PM_ANIMA_SLIDE: 滑动动画,页面从右往左出现,从左往右消失
117+
- [ ] LV_PM_ANIMA_SLIDE_SCALE: 滑动并缩放页面,页面从右往左先出现,再放大全屏
118+
- [ ] 更多动画开发中,欢迎贡献代码,开发过渡动画非常简单

‎src/anima.c

+24-4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ static void anima_ready_cb(lv_anim_t *anim)
2323
cb_data->cb(cb_data->pm_page);
2424
}
2525

26+
/**
27+
----------------------------------------------------------------------------------------------------------
28+
slide animation
29+
----------------------------------------------------------------------------------------------------------
30+
*/
31+
2632
static void _pm_slide_appear(lv_pm_page_t *pm_page, lv_pm_open_options_t *behavior, lv_pm_anima_complete_cb cb)
2733
{
2834
lv_coord_t width = lv_disp_get_hor_res(NULL);
@@ -38,12 +44,18 @@ static void _pm_slide_appear(lv_pm_page_t *pm_page, lv_pm_open_options_t *behavi
3844
lv_anim_init(&appear_anima);
3945
lv_anim_set_user_data(&appear_anima, (void *)cb_data);
4046
lv_anim_set_var(&appear_anima, pm_page->page);
41-
lv_anim_set_values(&appear_anima, width, 0);
47+
48+
if (pm_page->_back) {
49+
lv_anim_set_values(&appear_anima, -width, 0);
50+
} else {
51+
lv_anim_set_values(&appear_anima, width, 0);
52+
}
53+
54+
lv_anim_set_path_cb(&appear_anima, lv_anim_path_ease_out);
4255
lv_anim_set_time(&appear_anima, 500);
4356
lv_anim_set_repeat_count(&appear_anima, 1);
4457
lv_anim_set_exec_cb(&appear_anima, translateX_anima_cb);
4558
lv_anim_set_ready_cb(&appear_anima, anima_ready_cb);
46-
lv_anim_set_path_cb(&appear_anima, lv_anim_path_ease_out);
4759
lv_anim_start(&appear_anima);
4860
}
4961

@@ -62,7 +74,13 @@ static void _pm_slide_disAppear(lv_pm_page_t *pm_page, lv_pm_open_options_t *beh
6274
lv_anim_init(&disAppear_anima);
6375
lv_anim_set_user_data(&disAppear_anima, (void *)cb_data);
6476
lv_anim_set_var(&disAppear_anima, pm_page->page);
65-
lv_anim_set_values(&disAppear_anima, 0, -width);
77+
78+
if (pm_page->_back) {
79+
lv_anim_set_values(&disAppear_anima, 0, width);
80+
} else {
81+
lv_anim_set_values(&disAppear_anima, 0, -width);
82+
}
83+
6684
lv_anim_set_time(&disAppear_anima, 500);
6785
lv_anim_set_repeat_count(&disAppear_anima, 1);
6886
lv_anim_set_exec_cb(&disAppear_anima, translateX_anima_cb);
@@ -71,6 +89,8 @@ static void _pm_slide_disAppear(lv_pm_page_t *pm_page, lv_pm_open_options_t *beh
7189
lv_anim_start(&disAppear_anima);
7290
}
7391

92+
/** --------------------------------------------------------------------------------------------------- */
93+
7494
void _pm_anima_appear(lv_pm_page_t *pm_page, lv_pm_open_options_t *behavior, lv_pm_anima_complete_cb cb)
7595
{
7696
if (behavior == NULL || behavior->animation == LV_PM_ANIMA_NONE) {
@@ -105,4 +125,4 @@ void _pm_anima_disAppear(lv_pm_page_t *pm_page, lv_pm_open_options_t *behavior,
105125
cb(pm_page);
106126
break;
107127
}
108-
}
128+
}

‎src/pm.c

+13-7
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ lv_pm_page_t *lv_pm_create_page(uint8_t id)
5858
if (pm_page == NULL) {
5959
return NULL;
6060
}
61+
memset(pm_page, 0, sizeof(lv_pm_page_t));
62+
6163
lv_pm_router[id] = pm_page;
6264
lv_obj_t *page = lv_obj_create(lv_scr_act());
6365
lv_obj_remove_style_all(page);
@@ -82,6 +84,10 @@ uint8_t lv_pm_open_page(uint8_t id, lv_pm_open_options_t *behavior)
8284
lv_pm_history[lv_pm_history_len] = id;
8385
lv_pm_page_t *pm_page = lv_pm_router[id];
8486
lv_obj_t *page = pm_page->page;
87+
if (behavior) {
88+
pm_page->_options = *behavior;
89+
}
90+
pm_page->_back = false;
8591

8692
lv_obj_t *screen = lv_scr_act();
8793
// turn off the scroll bar temporarily when performing animation
@@ -91,18 +97,19 @@ uint8_t lv_pm_open_page(uint8_t id, lv_pm_open_options_t *behavior)
9197
uint8_t pid = lv_pm_history[lv_pm_history_len - 1];
9298
lv_pm_page_t *prev_pm_page = lv_pm_router[pid];
9399
lv_obj_t *prev_page = prev_pm_page->page;
100+
prev_pm_page->_back = false;
94101
if (prev_pm_page->willDisappear) {
95102
prev_pm_page->willDisappear(prev_page);
96103
}
97-
_pm_anima_disAppear(prev_pm_page, behavior, _disAppear_complete_cb);
104+
_pm_anima_disAppear(prev_pm_page, &pm_page->_options, _disAppear_complete_cb);
98105
}
99106

100107
pm_page->onLoad(page);
101108
lv_obj_clear_flag(page, LV_OBJ_FLAG_HIDDEN);
102109
if (pm_page->willAppear) {
103110
pm_page->willAppear(page);
104111
}
105-
_pm_anima_appear(pm_page, behavior, _appear_complete_cb);
112+
_pm_anima_appear(pm_page, &pm_page->_options, _appear_complete_cb);
106113

107114
lv_pm_history_len++;
108115
return 0;
@@ -115,29 +122,28 @@ uint8_t lv_pm_back()
115122
}
116123
uint8_t pid = lv_pm_history[lv_pm_history_len - 1];
117124
lv_pm_page_t *pm_page = lv_pm_router[pid];
125+
pm_page->_back = true;
118126
lv_obj_t *page = pm_page->page;
119127
lv_obj_t *screen = lv_scr_act();
120128
// turn off the scroll bar temporarily when performing animation
121129
lv_obj_set_scrollbar_mode(screen, LV_SCROLLBAR_MODE_OFF);
122-
lv_pm_open_options_t options = {
123-
.animation = LV_PM_ANIMA_SLIDE
124-
};
125130

126131
if (pm_page->willDisappear) {
127132
pm_page->willDisappear(page);
128133
}
129-
_pm_anima_disAppear(pm_page, &options, _back_disAppear_complete_cb);
134+
_pm_anima_disAppear(pm_page, &pm_page->_options, _back_disAppear_complete_cb);
130135

131136
lv_pm_history_len--;
132137
uint8_t prev_pid = lv_pm_history[lv_pm_history_len - 1];
133138
lv_pm_page_t *prev_pm_page = lv_pm_router[prev_pid];
134139
lv_obj_t *prev_page = prev_pm_page->page;
140+
prev_pm_page->_back = true;
135141

136142
if (prev_pm_page->willAppear) {
137143
prev_pm_page->willAppear(prev_page);
138144
}
139145
lv_obj_clear_flag(prev_pm_page->page, LV_OBJ_FLAG_HIDDEN);
140-
_pm_anima_appear(prev_pm_page, &options, _back_appear_complete_cb);
146+
_pm_anima_appear(prev_pm_page, &pm_page->_options, _back_appear_complete_cb);
141147

142148
return 0;
143149
}

‎src/pm.h

+10-7
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
#define LV_PM_MAJOR 0
88
#define LV_PM_MINOR 1
9-
#define LV_PM_PATCH 0
9+
#define LV_PM_PATCH 1
1010

1111
typedef void (*lv_pm_lifecycle)(lv_obj_t *page);
1212

@@ -32,6 +32,13 @@ enum LV_PM_OPEN_TARGET {
3232
LV_PM_TARGET_RESET = 2
3333
};
3434

35+
typedef struct _lv_pm_open_options_t
36+
{
37+
enum LV_PM_PAGE_ANIMA animation;
38+
enum LV_PM_OPEN_TARGET target;
39+
enum LV_PM_ANIMA_DIR direction;
40+
} lv_pm_open_options_t;
41+
3542
typedef struct _lv_pm_page_t
3643
{
3744
lv_obj_t *page;
@@ -41,14 +48,10 @@ typedef struct _lv_pm_page_t
4148
lv_pm_lifecycle willDisappear;
4249
lv_pm_lifecycle didDisappear;
4350
lv_pm_lifecycle unLoad;
51+
lv_pm_open_options_t _options;
52+
bool _back;
4453
} lv_pm_page_t;
4554

46-
typedef struct _lv_pm_open_options_t
47-
{
48-
enum LV_PM_PAGE_ANIMA animation;
49-
enum LV_PM_OPEN_TARGET target;
50-
enum LV_PM_ANIMA_DIR direction;
51-
} lv_pm_open_options_t;
5255

5356
uint8_t lv_pm_history_len;
5457

0 commit comments

Comments
 (0)
Please sign in to comment.