player_ui.c 29 KB

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