1 #include <stdio.h>
2 #include <stdlib.h>
3 
4 #include "aos/kernel.h"
5 #include "menu.h"
6 
7 // 添加离自己最近的子级目录
8 #include "aircraftBattle/aircraftBattle.h"
9 #include "barometer/barometer.h"
10 #include "compass/compass.h"
11 #include "greedySnake/greedySnake.h"
12 #include "gyroscope/gyroscope.h"
13 #include "homepage/homepage.h"
14 #include "humiture/humiture.h"
15 #include "lightmeter/lightmeter.h"
16 #include "musicbox/musicbox.h"
17 #include "shakeshake/shakeshake.h"
18 #include "kws/kws.h"
19 
20 #define KEY_CODE_BACK  (EDK_KEY_1 | EDK_KEY_2)
21 #define KEY_CODE_LEFT  EDK_KEY_1
22 #define KEY_CODE_RIGHT EDK_KEY_3
23 #define KEY_CODE_DOWN  EDK_KEY_4
24 
25 MENU_TYP *Menus[] = {
26     &homepage,
27     &humiture, &gyroscope, &shakeshake,  &compass,        &barometer,
28     &lightmeter, &musicbox,  &greedySnake, &aircraftBattle, &kws,
29 };
30 MENU_LIST_TYP MenuList = {Menus, sizeof(Menus)/sizeof(Menus[0])};
31 
32 MENU_TYP *pCurMenu = NULL;
33 key_code_cb app_key_code_cb = NULL;
34 
menu_list_fix(MENU_LIST_TYP * menuChildList,MENU_TYP * menuParent)35 void menu_list_fix(MENU_LIST_TYP *menuChildList, MENU_TYP *menuParent)
36 {
37     uint8_t curLevelMenuSize = menuChildList->MenuListSize;
38     printf("curLevelMenuSize %d\n", curLevelMenuSize);
39     for (uint8_t i = 0; i < curLevelMenuSize; i++) {
40         if (menuParent != NULL) {
41             menuParent->pChild = menuChildList->pMenuList[0];
42             menuChildList->pMenuList[i]->pParent = menuParent;
43         } else {
44             menuChildList->pMenuList[i]->pParent = NULL;
45         }
46         menuChildList->pMenuList[i]->pRight =
47             ((i == curLevelMenuSize - 1) ? menuChildList->pMenuList[0] :
48                                            menuChildList->pMenuList[i + 1]);
49         menuChildList->pMenuList[i]->pLeft =
50             ((i == 0) ? menuChildList->pMenuList[curLevelMenuSize - 1] :
51                         menuChildList->pMenuList[i - 1]);
52         MENU_LIST_TYP *pchildlist = menuChildList->pMenuList[i]->pChildrenList;
53         if (pchildlist != NULL)
54             printf("pchildlist->MenuListSize\n", pchildlist->MenuListSize);
55         if (pchildlist != NULL && pchildlist->MenuListSize > 0) {
56             printf("pchildlist->MenuListSize\n", pchildlist->MenuListSize);
57             menu_list_fix(menuChildList->pMenuList[i]->pChildrenList,
58                           menuChildList->pMenuList[i]);
59         }
60     }
61 }
62 
menu_init()63 void menu_init()
64 {
65     menu_list_fix(&MenuList, NULL);
66     pCurMenu = MenuList.pMenuList[0];
67     key_init(public_key_event_handle);
68     app_key_code_cb = menu_key_event_handle;
69     aos_task_new("menu_show_cover_task", menu_show_cover_task, NULL, 5000);
70 
71     if (pCurMenu->MenuCover->MenuCoverMode == MENU_COVER_NONE) {
72         menu_task_start(pCurMenu);
73     }
74 }
75 
menu_show_cover_task(void)76 static void menu_show_cover_task(void)
77 {
78     static int loading_draw_index = 0;
79     static int error_draw_index   = 0;
80     while (1) {
81         if (pCurMenu != NULL) {
82             // printf("%s state %d\n", pCurMenu->MenuName,
83             // pCurMenu->pMenuTask->menu_task_state);
84         }
85         if (pCurMenu != NULL &&
86             pCurMenu->pMenuTask->menu_task_state == MENU_TASK_IDLE) {
87             switch (pCurMenu->MenuCover->MenuCoverMode) {
88                 case MENU_COVER_NONE:
89                     printf("[E] You are not suppose to get here %s:%d\n",
90                            __func__, __LINE__);
91                     aos_msleep(1000);
92                     break;
93                 case MENU_COVER_TEXT:
94                     OLED_Clear();
95                     if (pCurMenu->MenuCover->text != NULL) {
96                         OLED_Show_String(22, 4, pCurMenu->MenuCover->text, 12,
97                                          1);
98                     }
99                     OLED_Icon_Draw(2, 24, &icon_skip_left, 0);
100                     OLED_Icon_Draw(122, 24, &icon_skip_right, 0);
101                     OLED_Refresh_GRAM();
102                     aos_msleep(200);
103                     break;
104                 case MENU_COVER_IMG:
105                     OLED_Clear();
106                     if (pCurMenu->MenuCover->img != NULL) {
107                         OLED_Icon_Draw(0, 0, pCurMenu->MenuCover->img, 1);
108                     }
109                     OLED_Icon_Draw(2, 24, &icon_skip_left, 0);
110                     OLED_Icon_Draw(122, 24, &icon_skip_right, 0);
111                     OLED_Refresh_GRAM();
112                     aos_msleep(200);
113                     break;
114                 case MENU_COVER_FUNC:
115                     if (pCurMenu->MenuCover->draw_func != NULL)
116                         pCurMenu->MenuCover->draw_func(
117                             &(pCurMenu->MenuCover->draw_index));
118                     break;
119                 default:
120                     aos_msleep(1000);
121                     break;
122             }
123         } else if (pCurMenu != NULL && (pCurMenu->pMenuTask->menu_task_state ==
124                                             MENU_TASK_UNINITING ||
125                                         pCurMenu->pMenuTask->menu_task_state ==
126                                             MENU_TASK_INITING)) {
127             menu_loading_draw(&loading_draw_index);
128         } else if (pCurMenu == NULL) {
129             menu_error_draw(&error_draw_index);
130         } else {
131             aos_msleep(500);
132         }
133     }
134 }
135 
menu_loading_draw(int * draw_index)136 void menu_loading_draw(int *draw_index)
137 {
138     (*draw_index)++;
139     if ((*draw_index) >= 8)
140         (*draw_index) = 0;
141 
142     OLED_Clear();
143     switch ((*draw_index)) {
144         case 0:
145             OLED_Icon_Draw(50, 4, &icon_loadlines0_32_32, 0);
146             OLED_Show_String(36, 42, "loading", 12, 1);
147             break;
148         case 1:
149             OLED_Icon_Draw(50, 4, &icon_loadlines1_32_32, 0);
150             OLED_Show_String(36, 42, "loading.", 12, 1);
151             break;
152         case 2:
153             OLED_Icon_Draw(50, 4, &icon_loadlines2_32_32, 0);
154             OLED_Show_String(36, 42, "loading..", 12, 1);
155             break;
156         case 3:
157             OLED_Icon_Draw(50, 4, &icon_loadlines3_32_32, 0);
158             OLED_Show_String(36, 42, "loading...", 12, 1);
159             break;
160         case 4:
161             OLED_Icon_Draw(50, 4, &icon_loadlines4_32_32, 0);
162             OLED_Show_String(36, 42, "loading", 12, 1);
163             break;
164         case 5:
165             OLED_Icon_Draw(50, 4, &icon_loadlines5_32_32, 0);
166             OLED_Show_String(36, 42, "loading.", 12, 1);
167             break;
168         case 6:
169             OLED_Icon_Draw(50, 4, &icon_loadlines6_32_32, 0);
170             OLED_Show_String(36, 42, "loading..", 12, 1);
171             break;
172         case 7:
173             OLED_Icon_Draw(50, 4, &icon_loadlines7_32_32, 0);
174             OLED_Show_String(36, 42, "loading...", 12, 1);
175             break;
176         default:
177             break;
178     }
179 
180     OLED_Refresh_GRAM();
181     aos_msleep(100);
182 }
183 
menu_error_draw(int * draw_index)184 void menu_error_draw(int *draw_index)
185 {
186     OLED_Clear();
187     OLED_Icon_Draw(54, 10, &icon_error_ufo, 1);
188     OLED_Show_String(15, 42, "Please reset me !", 12, 1);
189     OLED_Refresh_GRAM();
190     aos_msleep(500);
191 }
192 
public_key_event_handle(key_code_t key_code)193 static void public_key_event_handle(key_code_t key_code)
194 {
195     if (key_code == KEY_CODE_BACK) {
196         app_key_code_cb = menu_key_event_handle;
197         if (pCurMenu != NULL) {
198             if (pCurMenu->MenuCover->MenuCoverMode != MENU_COVER_NONE) {
199                 if (pCurMenu->pMenuTask->menu_task_state != MENU_TASK_RUNNING) {
200                     if (pCurMenu->pParent != NULL)
201                         pCurMenu = pCurMenu->pParent;
202                 } else {
203                     menu_task_exit(pCurMenu);
204                 }
205             } else {
206                 if (pCurMenu->pParent != NULL) {
207                     menu_task_exit(pCurMenu);
208                     pCurMenu = pCurMenu->pParent;
209                     if (pCurMenu->MenuCover->MenuCoverMode == MENU_COVER_NONE) {
210                         menu_task_start(pCurMenu);
211                     }
212                 }
213             }
214         }
215     } else {
216         if (app_key_code_cb != NULL) {
217             app_key_code_cb(key_code);
218         } else {
219             printf("app_key_code_cb is null\n");
220         }
221     }
222 }
223 
menu_task_start(MENU_TYP * pMenu)224 static int menu_task_start(MENU_TYP *pMenu)
225 {
226     if (pMenu == NULL) {
227         printf("pMenu null in %s:%d\n", __func__, __LINE__);
228         return -1;
229     }
230 
231     // 先卸载按键
232     app_key_code_cb = NULL;
233 
234     if (pMenu->pMenuTask != NULL) {
235         if (pMenu->pMenuTask->menu_task_state == MENU_TASK_IDLE) {
236             if (pMenu->pMenuTask->pMenuTaskInit != NULL) {
237                 pMenu->pMenuTask->menu_task_state = MENU_TASK_INITING;
238                 if (pMenu->pMenuTask->pMenuTaskInit() == 0) {
239                     pMenu->pMenuTask->menu_task_state = MENU_TASK_RUNNING;
240                     app_key_code_cb = (pMenu->pTaskKeyDeal == NULL) ?
241                                           menu_key_event_handle :
242                                           pMenu->pTaskKeyDeal;
243                     return 0;
244                 } else {
245                     printf("[E] %s task init func null\n", pMenu->MenuName);
246                     app_key_code_cb = menu_key_event_handle;
247                     return 1;
248                 }
249             } else {
250                 pMenu->pMenuTask->menu_task_state = MENU_TASK_IDLE;
251                 app_key_code_cb                   = menu_key_event_handle;
252                 return 1;
253             }
254         } else {
255             printf("[E] %s task state err %d\n", pMenu->MenuName,
256                    pMenu->pMenuTask->menu_task_state);
257             pMenu->pMenuTask->menu_task_state = MENU_TASK_IDLE;
258             app_key_code_cb                   = menu_key_event_handle;
259             return 1;
260         }
261     } else {
262         printf("[E] %s pMenuTask null in %s:%d\n", pMenu->MenuName, __func__,
263                __LINE__);
264         app_key_code_cb = menu_key_event_handle;
265         return 1;
266     }
267 }
268 
menu_task_exit(MENU_TYP * pMenu)269 static int menu_task_exit(MENU_TYP *pMenu)
270 {
271     if (pMenu == NULL) {
272         printf("pMenu null in %s:%d\n", __func__, __LINE__);
273         return -1;
274     }
275     app_key_code_cb = NULL;
276 
277     if (pMenu->pMenuTask != NULL) {
278         if (pMenu->pMenuTask->menu_task_state == MENU_TASK_RUNNING) {
279             if (pMenu->pMenuTask->pMenuTaskEnd != NULL) {
280                 pMenu->pMenuTask->menu_task_state = MENU_TASK_UNINITING;
281                 if (pMenu->pMenuTask->pMenuTaskEnd() == 0) {
282                     pMenu->pMenuTask->menu_task_state = MENU_TASK_IDLE;
283                     app_key_code_cb                   = menu_key_event_handle;
284                     return 0;
285                 } else {
286                     printf("[E] %s task exit fail\n", pMenu->MenuName);
287                     return 1;
288                 }
289             } else {
290                 pMenu->pMenuTask->menu_task_state = MENU_TASK_IDLE;
291                 app_key_code_cb                   = menu_key_event_handle;
292                 return 0;
293             }
294         } else {
295             pMenu->pMenuTask->menu_task_state = MENU_TASK_IDLE;
296             app_key_code_cb                   = menu_key_event_handle;
297             return 0;
298         }
299     } else {
300         app_key_code_cb = menu_key_event_handle;
301         return 0;
302     }
303 }
304 
menu_key_event_handle(key_code_t key_code)305 static void menu_key_event_handle(key_code_t key_code)
306 {
307     if (pCurMenu == NULL) {
308         printf("pCurMenu null in %s:%d\n", __func__, __LINE__);
309         return;
310     }
311 
312     switch (key_code) {
313         case 4:
314             if (pCurMenu->MenuCover->MenuCoverMode == MENU_COVER_NONE) {
315                 menu_task_exit(pCurMenu);
316                 pCurMenu = pCurMenu->pRight;
317             } else {
318                 if (pCurMenu->pMenuTask->menu_task_state == MENU_TASK_IDLE)
319                     pCurMenu = pCurMenu->pRight;
320             }
321 
322             break;
323         case KEY_CODE_LEFT:
324             if (pCurMenu->MenuCover->MenuCoverMode == MENU_COVER_NONE) {
325                 menu_task_exit(pCurMenu);
326                 pCurMenu = pCurMenu->pLeft;
327             } else {
328                 if (pCurMenu->pMenuTask->menu_task_state == MENU_TASK_IDLE)
329                     pCurMenu = pCurMenu->pLeft;
330             }
331             break;
332         case KEY_CODE_DOWN:
333             if (pCurMenu->pChild != NULL) {
334                 pCurMenu = pCurMenu->pChild;
335             }
336 
337             else {
338                 if (pCurMenu->MenuCover->MenuCoverMode != MENU_COVER_NONE) {
339                     menu_task_start(pCurMenu);
340                 }
341             }
342             break;
343         default:
344             break;
345     }
346 
347     switch (key_code) {
348         case KEY_CODE_RIGHT:
349         case KEY_CODE_LEFT:
350             if (pCurMenu == NULL) {
351                 printf("pCurMenu null in %s:%d\n", __func__, __LINE__);
352                 return;
353             }
354             if (pCurMenu->MenuCover->MenuCoverMode == MENU_COVER_NONE) {
355                 menu_task_start(pCurMenu);
356             }
357             break;
358     }
359 }
360