player_ui.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924
  1. #include <rtgui/rtgui.h>
  2. #include <rtgui/image.h>
  3. #include <rtgui/rtgui_system.h>
  4. #include <rtgui/widgets/view.h>
  5. #include <rtgui/widgets/label.h>
  6. #include <rtgui/widgets/list_view.h>
  7. #include <rtgui/widgets/workbench.h>
  8. #include <rtgui/widgets/filelist_view.h>
  9. #include <string.h>
  10. #include <dfs_posix.h>
  11. #include "mp3.h"
  12. #include "picture.h"
  13. #include "player_ui.h"
  14. #include "player_bg.h"
  15. #include "play_list.h"
  16. #include "station_list.h"
  17. #include "play.hdh"
  18. #include "stop.hdh"
  19. #define RADIO_FN "/radio.pls"
  20. const static char *time_bg_xpm[] = {
  21. "48 20 7 1",
  22. ". c #007DC6",
  23. "+ c #0079C6",
  24. "@ c #0079BD",
  25. "# c #0075BD",
  26. "$ c #0071BD",
  27. "% c #0071B5",
  28. "& c #006DB5",
  29. "................................................",
  30. "................................................",
  31. "................................................",
  32. "................................................",
  33. "................................................",
  34. "++++++++++++++++++++++++++++++++++++++++++++++++",
  35. "++++++++++++++++++++++++++++++++++++++++++++++++",
  36. "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
  37. "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
  38. "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",
  39. "################################################",
  40. "################################################",
  41. "################################################",
  42. "################################################",
  43. "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$",
  44. "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%",
  45. "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%",
  46. "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&",
  47. "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&",
  48. "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&",
  49. "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"};
  50. static struct rtgui_view* home_view;
  51. static struct rtgui_list_view* function_view;
  52. static struct rtgui_workbench* workbench;
  53. static rtgui_timer_t* info_timer;
  54. static rt_thread_t player_ui_tid = RT_NULL;
  55. static enum PLAYER_MODE player_mode = PLAYER_STOP;
  56. static enum PLAYER_STEP next_step = PLAYER_STEP_STOP;
  57. static struct tag_info tinfo;
  58. static rt_uint32_t play_time;
  59. static rtgui_image_t *time_bg_image;
  60. void player_play_file(const char* fn);
  61. void player_play_url(const char* url);
  62. static void info_timer_timeout(rtgui_timer_t* timer, void* parameter)
  63. {
  64. struct rtgui_dc* dc;
  65. rtgui_color_t saved;
  66. dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(home_view));
  67. if (dc == RT_NULL) return ;
  68. saved = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(home_view));
  69. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(home_view)) = RTGUI_RGB(206, 231, 255);
  70. rtgui_dc_draw_hline(dc, 14, 14 + (tinfo.position * 212) / tinfo.duration, 75);
  71. if ((player_mode == PLAYER_PLAY_RADIO) && ((tinfo.position * 212 + 14)/tinfo.duration) < 226)
  72. {
  73. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(home_view)) = RTGUI_RGB(82, 199, 16);
  74. rtgui_dc_draw_hline(dc, 14 + (tinfo.position * 212) / tinfo.duration, 226, 75);
  75. }
  76. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(home_view)) = saved;
  77. if (player_mode == PLAYER_PLAY_FILE)
  78. {
  79. rtgui_rect_t rect;
  80. char line[32];
  81. play_time++;
  82. rt_snprintf(line, sizeof(line), "%3d:%02d", play_time / 60, play_time % 60);
  83. rect.x1 = 172; rect.y1 = 39;
  84. rect.x2 = 220; rect.y2 = 59;
  85. rtgui_image_blit(time_bg_image, dc, &rect);
  86. rtgui_dc_draw_text(dc, line, &rect);
  87. }
  88. rtgui_dc_end_drawing(dc);
  89. }
  90. static void player_update_tag_info(struct rtgui_dc* dc)
  91. {
  92. rtgui_rect_t rect;
  93. char line[32];
  94. rtgui_color_t saved;
  95. rtgui_image_t *background;
  96. saved = rtgui_dc_get_color(dc);
  97. rtgui_dc_set_color(dc, black);
  98. rect.x1 = 0; rect.y1 = 0;
  99. rect.x2 = 240; rect.y2 = 65;
  100. /* draw background */
  101. background = rtgui_image_create_from_file("hdc", "/resource/bg.hdc", RT_FALSE);
  102. if (background != RT_NULL)
  103. {
  104. rtgui_image_blit(background, dc, &rect);
  105. rtgui_image_destroy(background);
  106. background = RT_NULL;
  107. }
  108. else
  109. {
  110. rtgui_dc_fill_rect(dc, &rect);
  111. }
  112. /* draw playing information */
  113. rect.x1 = 28; rect.y1 = 12;
  114. rect.x2 = 220; rect.y2 = rect.y1 + 16;
  115. if (player_mode == PLAYER_STOP)
  116. {
  117. rt_snprintf(line, sizeof(line), "网络收音机");
  118. rtgui_dc_draw_text(dc, line, &rect);
  119. }
  120. else
  121. rtgui_dc_draw_text(dc, tinfo.title, &rect);
  122. rect.x1 = 28; rect.y1 = 39;
  123. rect.x2 = 220; rect.y2 = 59;
  124. if (player_mode == PLAYER_STOP)
  125. {
  126. rt_snprintf(line, sizeof(line), "radio.rt-thread.org");
  127. rtgui_dc_draw_text(dc, line, &rect);
  128. }
  129. else
  130. rtgui_dc_draw_text(dc, tinfo.artist, &rect);
  131. if ((tinfo.duration != 0) && player_mode == PLAYER_PLAY_FILE)
  132. {
  133. play_time = 0;
  134. rect.x1 = 172;
  135. rt_snprintf(line, sizeof(line), " 0:00");
  136. rtgui_dc_draw_text(dc, line, &rect);
  137. }
  138. rtgui_dc_set_color(dc, saved);
  139. }
  140. static rt_uint32_t read_line(int fd, char* line, rt_uint32_t line_size)
  141. {
  142. char *pos, *next;
  143. rt_uint32_t length;
  144. length = read(fd, line, line_size);
  145. if (length > 0)
  146. {
  147. pos = strstr(line, "\r\n");
  148. if (pos == RT_NULL)
  149. {
  150. pos = strstr(line, "\n");
  151. next = pos ++;
  152. }
  153. else next = pos + 2;
  154. if (pos != RT_NULL)
  155. {
  156. *pos = '\0';
  157. /* move back */
  158. lseek(fd, -(length - (next - line)), SEEK_CUR);
  159. length = pos - line;
  160. }
  161. else length = 0;
  162. }
  163. return length;
  164. }
  165. static void function_play_radio(void* parameter)
  166. {
  167. struct station_list* list;
  168. struct station_item* item;
  169. list = station_list_create(RADIO_FN);
  170. if (list != RT_NULL)
  171. {
  172. item = station_list_select(list, workbench);
  173. if (item != RT_NULL)
  174. {
  175. player_play_url(item->url);
  176. }
  177. station_list_destroy(list);
  178. }
  179. }
  180. static void function_radio_list_update(void* parameter)
  181. {
  182. extern void update_radio_list_req(void);
  183. extern void update_radio_thread(void* parameter);
  184. extern rt_mq_t update_radio_mq;
  185. rt_thread_t update_radio_list_thread;
  186. if(update_radio_mq == RT_NULL)
  187. {
  188. update_radio_mq = rt_mq_create("updateRadioList", sizeof(struct player_request),
  189. 1, RT_IPC_FLAG_FIFO);
  190. RT_ASSERT(update_radio_mq != RT_NULL);
  191. update_radio_list_thread = rt_thread_create("update_bg", update_radio_thread, RT_NULL,
  192. 1024 ,20, 5);
  193. if (update_radio_list_thread == RT_NULL) rt_kprintf("updateRadioList thread init failed\n");
  194. else
  195. {
  196. rt_thread_startup(update_radio_list_thread);
  197. update_radio_list_req();
  198. }
  199. }
  200. return;
  201. }
  202. static void function_filelist(void* parameter)
  203. {
  204. rtgui_rect_t rect;
  205. rtgui_filelist_view_t *view;
  206. rtgui_widget_get_rect(RTGUI_WIDGET(workbench), &rect);
  207. view = rtgui_filelist_view_create(workbench, "/", "*.*", &rect);
  208. if (view != RT_NULL)
  209. {
  210. if (rtgui_view_show(RTGUI_VIEW(view), RT_TRUE) == RTGUI_MODAL_OK)
  211. {
  212. char fn[64];
  213. /* get open file */
  214. rt_snprintf(fn, 64, "%s/%s", view->current_directory,
  215. view->items[view->current_item].name);
  216. if (strstr(view->items[view->current_item].name , ".mp3") != RT_NULL ||
  217. strstr(view->items[view->current_item].name , ".MP3") != RT_NULL ||
  218. strstr(view->items[view->current_item].name , ".wav") != RT_NULL ||
  219. strstr(view->items[view->current_item].name , ".WAV") != RT_NULL)
  220. {
  221. /* clear old play list */
  222. play_list_clear();
  223. play_list_append(fn);
  224. player_mode = PLAYER_PLAY_FILE;
  225. next_step = PLAYER_STEP_STOP;
  226. player_play_file(play_list_start());
  227. }
  228. else if (strstr(view->items[view->current_item].name , ".m3u") != RT_NULL ||
  229. strstr(view->items[view->current_item].name , ".M3U") != RT_NULL)
  230. {
  231. /* read all of music filename to a list */
  232. int fd;
  233. char line[64];
  234. fd = open(fn, O_RDONLY, 0);
  235. if (fd >= 0)
  236. {
  237. rt_uint32_t length;
  238. length = read_line(fd, line, sizeof(line));
  239. /* clear old play list */
  240. play_list_clear();
  241. do
  242. {
  243. length = read_line(fd, line, sizeof(line));
  244. if (length > 0)
  245. {
  246. if (strstr(line, "http:") != RT_NULL)
  247. {
  248. play_list_append(line);
  249. }
  250. else if (line[0] != '/')
  251. {
  252. rt_snprintf(fn, sizeof(fn), "%s/%s", view->current_directory, line);
  253. play_list_append(fn);
  254. }
  255. else play_list_append(line);
  256. }
  257. } while (length > 0);
  258. close(fd);
  259. if (play_list_items() > 0)
  260. {
  261. player_mode = PLAYER_PLAY_FILE;
  262. next_step = PLAYER_STEP_NEXT;
  263. player_play_file(play_list_start());
  264. }
  265. }
  266. }
  267. }
  268. /* destroy view */
  269. rtgui_filelist_view_destroy(view);
  270. }
  271. return;
  272. }
  273. static void function_device(void* parameter)
  274. {
  275. rtgui_view_t *view;
  276. extern rtgui_view_t* device_view_create(rtgui_workbench_t* workbench);
  277. view = device_view_create(workbench);
  278. if (view != RT_NULL)
  279. {
  280. rtgui_view_show(view, RT_FALSE);
  281. }
  282. return;
  283. }
  284. static void function_player(void* parameter)
  285. {
  286. rtgui_view_show(home_view, RT_FALSE);
  287. return;
  288. }
  289. static void function_show_picure(void* parameter)
  290. {
  291. rtgui_view_t *view;
  292. view = picture_view_create(workbench);
  293. if (view != RT_NULL)
  294. {
  295. rtgui_view_show(view, RT_TRUE);
  296. rtgui_view_destroy(view);
  297. }
  298. return;
  299. }
  300. void function_action(void* parameter)
  301. {
  302. rt_kprintf("item action!\n");
  303. return;
  304. }
  305. void function_cable(void* parameter)
  306. {
  307. extern void USB_cable(void);
  308. USB_cable();
  309. }
  310. const struct rtgui_list_item function_list[] =
  311. {
  312. {"选择电台", RT_NULL, function_play_radio, RT_NULL},
  313. {"更新电台", RT_NULL, function_radio_list_update, RT_NULL},
  314. {"播放文件", RT_NULL, function_filelist, RT_NULL},
  315. {"浏览图片", RT_NULL, function_show_picure, RT_NULL},
  316. {"设备信息", RT_NULL, function_device, RT_NULL},
  317. {"选项设置", RT_NULL, function_action, RT_NULL},
  318. {"USB 联机", RT_NULL, function_cable, RT_NULL},
  319. {"返回播放器", RT_NULL, function_player, RT_NULL},
  320. };
  321. void player_set_position(rt_uint32_t position)
  322. {
  323. if (player_mode != PLAYER_PLAY_RADIO)
  324. {
  325. tinfo.position = position / (tinfo.bit_rate / 8);
  326. }
  327. else
  328. {
  329. tinfo.position = position;
  330. }
  331. }
  332. void player_set_title(const char* title)
  333. {
  334. strncpy(tinfo.title, title, 40);
  335. }
  336. void player_set_buffer_status(rt_bool_t buffering)
  337. {
  338. if (buffering == RT_TRUE)
  339. strncpy(tinfo.artist, "缓冲中...", 40);
  340. else
  341. strncpy(tinfo.artist, "播放中...", 40);
  342. }
  343. enum PLAYER_MODE player_get_mode()
  344. {
  345. return player_mode;
  346. }
  347. void player_play_file(const char* fn)
  348. {
  349. struct rtgui_dc* dc;
  350. rtgui_color_t saved;
  351. rt_bool_t is_mp3;
  352. is_mp3 = RT_FALSE;
  353. if (strstr(fn, ".mp3") != RT_NULL ||
  354. strstr(fn, ".MP3") != RT_NULL)
  355. is_mp3 = RT_TRUE;
  356. else if (strstr(fn, ".wav") != RT_NULL ||
  357. strstr(fn, ".wav") != RT_NULL)
  358. is_mp3 = RT_FALSE;
  359. else return; /* not supported audio format */
  360. if (is_mp3 == RT_TRUE)
  361. {
  362. /* get music tag information */
  363. mp3_get_info(fn, &tinfo);
  364. if (tinfo.title[0] == '\0')
  365. rt_snprintf(tinfo.title, sizeof(tinfo.title), "<未知名音乐>");
  366. }
  367. else
  368. {
  369. /* wav file */
  370. rt_snprintf(tinfo.title, sizeof(tinfo.title), "<未知名音乐>");
  371. rt_snprintf(tinfo.artist, sizeof(tinfo.title), "<wav音乐>");
  372. tinfo.duration = 0;
  373. }
  374. /* set player mode */
  375. player_mode = PLAYER_PLAY_FILE;
  376. dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(home_view));
  377. if (dc != RT_NULL)
  378. {
  379. rtgui_rect_t play_rect;
  380. rtgui_image_t *button;
  381. /* update tag information */
  382. player_update_tag_info(dc);
  383. /* reset progress bar */
  384. saved = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(home_view));
  385. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(home_view)) = RTGUI_RGB(82, 199, 16);
  386. rtgui_dc_draw_hline(dc, 14, 226, 75);
  387. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(home_view)) = saved;
  388. /* update play button */
  389. button = rtgui_image_create_from_mem("hdc",
  390. play_hdh, sizeof(play_hdh), RT_FALSE);
  391. play_rect.x1 = 32; play_rect.y1 = 92;
  392. play_rect.x2 = 61; play_rect.y2 = 114;
  393. rtgui_image_blit(button, dc, &play_rect);
  394. rtgui_image_destroy(button);
  395. rtgui_dc_end_drawing(dc);
  396. }
  397. rtgui_view_show(home_view, RT_FALSE);
  398. player_play_req(fn);
  399. }
  400. void player_play_url(const char* url)
  401. {
  402. struct rtgui_dc* dc;
  403. /* set music tag information */
  404. strncpy(tinfo.title, "网络电台", 40);
  405. player_set_buffer_status(RT_TRUE);
  406. tinfo.duration = 320 * 1024; /* 320 k */
  407. /* set player mode */
  408. player_mode = PLAYER_PLAY_RADIO;
  409. dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(home_view));
  410. if (dc != RT_NULL)
  411. {
  412. rtgui_rect_t play_rect;
  413. rtgui_image_t *button;
  414. /* update tag information */
  415. player_update_tag_info(dc);
  416. /* update play button */
  417. button = rtgui_image_create_from_mem("hdc",
  418. play_hdh, sizeof(play_hdh), RT_FALSE);
  419. play_rect.x1 = 32; play_rect.y1 = 92;
  420. play_rect.x2 = 61; play_rect.y2 = 114;
  421. rtgui_image_blit(button, dc, &play_rect);
  422. rtgui_image_destroy(button);
  423. rtgui_dc_end_drawing(dc);
  424. }
  425. rtgui_view_show(home_view, RT_FALSE);
  426. player_play_req(url);
  427. }
  428. static rt_bool_t home_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
  429. {
  430. if (event->type == RTGUI_EVENT_PAINT)
  431. {
  432. struct rtgui_dc* dc;
  433. struct rtgui_rect rect;
  434. rtgui_color_t saved;
  435. rtgui_image_t *background;
  436. dc = rtgui_dc_begin_drawing(widget);
  437. if (dc == RT_NULL) return RT_FALSE;
  438. rtgui_widget_get_rect(widget, &rect);
  439. saved = RTGUI_WIDGET_FOREGROUND(widget);
  440. /* draw background */
  441. background = rtgui_image_create_from_file("hdc", "/resource/bg.hdc", RT_FALSE);
  442. if (background != RT_NULL)
  443. {
  444. rtgui_image_t *play;
  445. rtgui_rect_t play_rect;
  446. rtgui_image_blit(background, dc, &rect);
  447. rtgui_image_destroy(background);
  448. background = RT_NULL;
  449. if (player_mode == PLAYER_STOP)
  450. play = rtgui_image_create_from_mem("hdc", stop_hdh, sizeof(stop_hdh), RT_FALSE);
  451. else
  452. play = rtgui_image_create_from_mem("hdc", play_hdh, sizeof(play_hdh), RT_FALSE);
  453. play_rect.x1 = 32; play_rect.y1 = 92;
  454. play_rect.x2 = 61; play_rect.y2 = 114;
  455. rtgui_image_blit(play, dc, &play_rect);
  456. rtgui_image_destroy(play);
  457. }
  458. else
  459. {
  460. rtgui_dc_fill_rect(dc, &rect);
  461. }
  462. /* draw playing information */
  463. rtgui_dc_set_color(dc, black);
  464. {
  465. char line[32];
  466. rect.x1 = 28; rect.y1 = 12;
  467. rect.x2 = 220; rect.y2 = rect.y1 + 16;
  468. if (player_mode == PLAYER_STOP)
  469. {
  470. rt_snprintf(line, sizeof(line), "网络收音机");
  471. rtgui_dc_draw_text(dc, line, &rect);
  472. }
  473. else
  474. rtgui_dc_draw_text(dc, tinfo.title, &rect);
  475. rect.x1 = 28; rect.y1 = 39;
  476. rect.x2 = 170; rect.y2 = 59;
  477. if (player_mode == PLAYER_STOP)
  478. {
  479. rect.x2 = 220;
  480. rt_snprintf(line, sizeof(line), "radio.rt-thread.org");
  481. rtgui_dc_draw_text(dc, line, &rect);
  482. }
  483. else
  484. rtgui_dc_draw_text(dc, tinfo.artist, &rect);
  485. if ((tinfo.duration != 0) && (player_mode == PLAYER_PLAY_FILE))
  486. {
  487. rt_uint32_t t = player_mode == PLAYER_STOP ? tinfo.duration : play_time;
  488. rect.x1 = 172; rect.x2 = 220;
  489. rt_snprintf(line, sizeof(line), "%3d:%02d", t / 60, t % 60);
  490. rtgui_dc_draw_text(dc, line, &rect);
  491. }
  492. }
  493. RTGUI_WIDGET_FOREGROUND(widget) = RTGUI_RGB(82, 199, 16);
  494. rtgui_dc_draw_hline(dc, 14, 226, 75);
  495. RTGUI_WIDGET_FOREGROUND(widget) = saved;
  496. if (player_mode == PLAYER_PLAY_FILE)
  497. {
  498. char line[32];
  499. rt_uint32_t index;
  500. struct play_item* item;
  501. rect.x1 = 20; rect.y1 = 150;
  502. rect.x2 = 170; rect.y2 = 168;
  503. for (index = 0; index < play_list_items() && index < 8; index ++)
  504. {
  505. item = play_list_item(index);
  506. rtgui_dc_draw_text(dc, item->title, &rect);
  507. rect.x1 = 172; rect.x2 = 220;
  508. rt_snprintf(line, sizeof(line), "%3d:%02d", item->duration / 60, item->duration % 60);
  509. rtgui_dc_draw_text(dc, line, &rect);
  510. /* move to next item */
  511. rect.x1 = 20; rect.x2 = 170;
  512. rect.y1 += 18; rect.y2 += 18;
  513. }
  514. }
  515. rtgui_dc_end_drawing(dc);
  516. return RT_FALSE;
  517. }
  518. else if (event->type == RTGUI_EVENT_KBD)
  519. {
  520. struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
  521. if (ekbd->type == RTGUI_KEYDOWN)
  522. {
  523. switch (ekbd->key)
  524. {
  525. case RTGUIK_RIGHT:
  526. if (player_mode == PLAYER_PLAY_FILE && play_list_items() > 0)
  527. {
  528. player_stop_req();
  529. next_step = PLAYER_STEP_NEXT;
  530. }
  531. break;
  532. case RTGUIK_LEFT:
  533. if (player_mode == PLAYER_PLAY_FILE && play_list_items() > 0)
  534. {
  535. player_stop_req();
  536. next_step = PLAYER_STEP_PREV;
  537. }
  538. break;
  539. case RTGUIK_RETURN:
  540. if (player_is_playing() == RT_TRUE)
  541. {
  542. player_stop_req();
  543. next_step = PLAYER_STEP_STOP;
  544. }
  545. else
  546. {
  547. if ((player_mode == PLAYER_STOP) && (play_list_items() > 0))
  548. {
  549. next_step = PLAYER_STEP_NEXT;
  550. player_play_file(play_list_current_item());
  551. }
  552. }
  553. break;
  554. case RTGUIK_DOWN:
  555. rtgui_view_show(RTGUI_VIEW(function_view), RT_FALSE);
  556. break;
  557. }
  558. }
  559. return RT_FALSE;
  560. }
  561. else if (event->type == RTGUI_EVENT_COMMAND)
  562. {
  563. struct rtgui_event_command* ecmd = (struct rtgui_event_command*)event;
  564. switch (ecmd->command_id)
  565. {
  566. case PLAYER_REQUEST_PLAY_SINGLE_FILE:
  567. case PLAYER_REQUEST_PLAY_LIST:
  568. rtgui_timer_start(info_timer);
  569. break;
  570. case PLAYER_REQUEST_STOP:
  571. {
  572. rtgui_timer_stop(info_timer);
  573. switch (next_step)
  574. {
  575. case PLAYER_STEP_STOP:
  576. // #define TEST_MODE
  577. #ifdef TEST_MODE
  578. player_play_file(play_list_start());
  579. next_step = PLAYER_STEP_STOP;
  580. #else
  581. {
  582. struct rtgui_dc* dc;
  583. rtgui_color_t saved;
  584. rtgui_image_t *button;
  585. rtgui_rect_t play_rect;
  586. player_mode = PLAYER_STOP;
  587. dc = rtgui_dc_begin_drawing(widget);
  588. if (dc == RT_NULL) return RT_FALSE;
  589. player_update_tag_info(dc);
  590. saved = RTGUI_WIDGET_FOREGROUND(widget);
  591. RTGUI_WIDGET_FOREGROUND(widget) = RTGUI_RGB(82, 199, 16);
  592. rtgui_dc_draw_hline(dc, 14, 226, 75);
  593. /* update play button */
  594. button = rtgui_image_create_from_mem("hdc", stop_hdh, sizeof(stop_hdh), RT_FALSE);
  595. play_rect.x1 = 32; play_rect.y1 = 92;
  596. play_rect.x2 = 61; play_rect.y2 = 114;
  597. rtgui_image_blit(button, dc, &play_rect);
  598. rtgui_image_destroy(button);
  599. RTGUI_WIDGET_FOREGROUND(widget) = saved;
  600. rtgui_dc_end_drawing(dc);
  601. }
  602. #endif
  603. break;
  604. case PLAYER_STEP_NEXT:
  605. if (play_list_is_end() == RT_TRUE)
  606. {
  607. struct rtgui_dc* dc;
  608. rtgui_color_t saved;
  609. rtgui_image_t *button;
  610. rtgui_rect_t play_rect;
  611. /* set stat */
  612. next_step = PLAYER_STEP_STOP;
  613. player_mode = PLAYER_STOP;
  614. /* update UI */
  615. dc = rtgui_dc_begin_drawing(widget);
  616. if (dc == RT_NULL) return RT_FALSE;
  617. player_update_tag_info(dc);
  618. saved = RTGUI_WIDGET_FOREGROUND(widget);
  619. RTGUI_WIDGET_FOREGROUND(widget) = RTGUI_RGB(82, 199, 16);
  620. rtgui_dc_draw_hline(dc, 14, 226, 75);
  621. /* update play button */
  622. button = rtgui_image_create_from_mem("hdc",
  623. stop_hdh, sizeof(stop_hdh), RT_FALSE);
  624. play_rect.x1 = 32; play_rect.y1 = 92;
  625. play_rect.x2 = 61; play_rect.y2 = 114;
  626. rtgui_image_blit(button, dc, &play_rect);
  627. rtgui_image_destroy(button);
  628. RTGUI_WIDGET_FOREGROUND(widget) = saved;
  629. rtgui_dc_end_drawing(dc);
  630. }
  631. else
  632. {
  633. player_play_file(play_list_next());
  634. next_step = PLAYER_STEP_NEXT;
  635. }
  636. break;
  637. case PLAYER_STEP_PREV:
  638. player_play_file(play_list_prev());
  639. next_step = PLAYER_STEP_NEXT;
  640. break;
  641. };
  642. }
  643. break;
  644. case PLAYER_REQUEST_FREEZE:
  645. {
  646. /* stop play */
  647. if (player_is_playing() == RT_TRUE)
  648. {
  649. player_stop_req();
  650. next_step = PLAYER_STEP_STOP;
  651. }
  652. /* delay some tick */
  653. rt_thread_delay(50);
  654. /* show a modal view */
  655. {
  656. rtgui_view_t *view;
  657. rtgui_label_t *label;
  658. rtgui_rect_t rect = {0, 0, 150, 150}, container_rect;
  659. rtgui_graphic_driver_get_default_rect(&container_rect);
  660. /* set centre */
  661. rtgui_rect_moveto_align(&container_rect, &rect, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
  662. view = rtgui_view_create("USB");
  663. rtgui_workbench_add_view(workbench, view);
  664. /* set container to window rect */
  665. container_rect = rect;
  666. rect.x1 = 0; rect.y1 = 0;
  667. rect.x2 = 120; rect.y2 = 20;
  668. label = rtgui_label_create("USB 联机中...");
  669. rtgui_rect_moveto_align(&container_rect, &rect, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
  670. rtgui_widget_set_rect(RTGUI_WIDGET(label), &rect);
  671. rtgui_container_add_child(RTGUI_CONTAINER(view), RTGUI_WIDGET(label));
  672. rtgui_view_show(view, RT_TRUE);
  673. /* never reach hear */
  674. }
  675. }
  676. default:
  677. break;
  678. }
  679. return RT_FALSE;
  680. }
  681. return rtgui_view_event_handler(widget, event);
  682. }
  683. rt_bool_t player_workbench_event_handler(rtgui_widget_t *widget, rtgui_event_t *event)
  684. {
  685. if (event->type == RTGUI_EVENT_KBD)
  686. {
  687. struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
  688. if (((ekbd->type == RTGUI_KEYUP) && ekbd->key == RTGUIK_HOME)
  689. && !RTGUI_WORKBENCH_IS_MODAL_MODE(workbench))
  690. {
  691. /* active home view */
  692. if (workbench->current_view != home_view)
  693. {
  694. rtgui_view_show(home_view, RT_FALSE);
  695. return RT_FALSE;
  696. }
  697. }
  698. }
  699. return rtgui_workbench_event_handler(widget, event);
  700. }
  701. static void player_entry(void* parameter)
  702. {
  703. rt_mq_t mq;
  704. rtgui_rect_t rect;
  705. mq = rt_mq_create("ply_ui", 256, 4, RT_IPC_FLAG_FIFO);
  706. rtgui_thread_register(rt_thread_self(), mq);
  707. /* create information timer */
  708. info_timer = rtgui_timer_create(RT_TICK_PER_SECOND, RT_TIMER_FLAG_PERIODIC, info_timer_timeout, RT_NULL);
  709. time_bg_image = rtgui_image_create_from_mem("xpm", (rt_uint8_t *) time_bg_xpm, sizeof(time_bg_xpm), RT_TRUE);
  710. workbench = rtgui_workbench_create("main", "workbench");
  711. if (workbench == RT_NULL) return;
  712. rtgui_widget_set_event_handler(RTGUI_WIDGET(workbench), player_workbench_event_handler);
  713. /* add home view */
  714. home_view = rtgui_view_create("Home");
  715. rtgui_widget_set_event_handler(RTGUI_WIDGET(home_view), home_view_event_handler);
  716. rtgui_workbench_add_view(workbench, home_view);
  717. /* this view can be focused */
  718. RTGUI_WIDGET(home_view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
  719. /* set widget focus */
  720. rtgui_widget_focus(RTGUI_WIDGET(home_view));
  721. rtgui_view_show(home_view, RT_FALSE);
  722. /* add function view */
  723. rtgui_widget_get_rect(RTGUI_WIDGET(workbench), &rect);
  724. function_view = rtgui_list_view_create(function_list,
  725. sizeof(function_list)/sizeof(struct rtgui_list_item),
  726. &rect);
  727. rtgui_workbench_add_view(workbench, RTGUI_VIEW(function_view));
  728. rtgui_workbench_event_loop(workbench);
  729. rtgui_thread_deregister(rt_thread_self());
  730. rt_mq_delete(mq);
  731. }
  732. void player_notify_play(void)
  733. {
  734. struct rtgui_event_command ecmd;
  735. RTGUI_EVENT_COMMAND_INIT(&ecmd);
  736. ecmd.type = RTGUI_CMD_USER_INT;
  737. ecmd.command_id = PLAYER_REQUEST_PLAY_SINGLE_FILE;
  738. rtgui_thread_send(player_ui_tid, &ecmd.parent, sizeof(ecmd));
  739. }
  740. void player_notify_stop()
  741. {
  742. struct rtgui_event_command ecmd;
  743. RTGUI_EVENT_COMMAND_INIT(&ecmd);
  744. ecmd.type = RTGUI_CMD_USER_INT;
  745. ecmd.command_id = PLAYER_REQUEST_STOP;
  746. rtgui_thread_send(player_ui_tid, &ecmd.parent, sizeof(ecmd));
  747. }
  748. void player_ui_init()
  749. {
  750. player_ui_tid = rt_thread_create("ply_ui", player_entry, RT_NULL,
  751. 0x800, 25, 5);
  752. if (player_ui_tid != RT_NULL)
  753. rt_thread_startup(player_ui_tid);
  754. }
  755. void player_ui_freeze()
  756. {
  757. struct rtgui_event_command ecmd;
  758. /* check whether UI starts. */
  759. if (home_view == RT_NULL || workbench == RT_NULL) return;
  760. RTGUI_EVENT_COMMAND_INIT(&ecmd);
  761. ecmd.type = RTGUI_CMD_USER_INT;
  762. ecmd.command_id = PLAYER_REQUEST_FREEZE;
  763. rtgui_thread_send(player_ui_tid, &ecmd.parent, sizeof(ecmd));
  764. }