playlst.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:13k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: playlist.c 332 2005-11-06 14:31:57Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../../common/common.h"
  24. #include "../win.h"
  25. #include "playlst.h"
  26. #include "openfile_win32.h"
  27. #include "resource.h"
  28. #if defined(TARGET_WINCE) || defined(TARGET_WIN32)
  29. #ifndef STRICT
  30. #define STRICT
  31. #endif
  32. #include <windows.h>
  33. #if _MSC_VER > 1000
  34. #pragma warning(disable : 4201)
  35. #endif
  36. #include <commctrl.h>
  37. #define MSG_PLAYER2 WM_APP + 0x300
  38. typedef struct playlistwin
  39. {
  40. win Win;
  41. HWND WndList;
  42. int DlgWidth[3];
  43. player* Player;
  44. DWORD ThreadId;
  45. int Pos;
  46. int Current;
  47. bool_t InUpdate;
  48. } playlistwin;
  49. static const datatable Params[] =
  50. {
  51. { PLAYLIST_WIDTH_NAME, TYPE_INT, DF_SETUP|DF_HIDDEN },
  52. { PLAYLIST_WIDTH_LENGTH,TYPE_INT, DF_SETUP|DF_HIDDEN },
  53. { PLAYLIST_WIDTH_URL, TYPE_INT, DF_SETUP|DF_HIDDEN },
  54. DATATABLE_END(PLAYLIST_ID)
  55. };
  56. static void UpdateList(playlistwin* p)
  57. {
  58. tchar_t s[256];
  59. tchar_t s2[256];
  60. LVITEM Item;
  61. tick_t Length;
  62. int i;
  63. int Count=0;
  64. p->Current = -1;
  65. p->Player->Get(p->Player,PLAYER_LIST_COUNT,&Count,sizeof(int));
  66. p->Player->Get(p->Player,PLAYER_LIST_CURRENT,&p->Current,sizeof(int));
  67. i = ListView_GetItemCount(p->WndList);
  68. while (i > Count)
  69. ListView_DeleteItem(p->WndList,--i);
  70. Item.mask=LVIF_TEXT;
  71. Item.pszText=T("");
  72. Item.cchTextMax=1;
  73. Item.iSubItem=0;
  74. while (i < Count)
  75. {
  76. Item.iItem = i++;
  77. ListView_InsertItem(p->WndList,&Item);
  78. }
  79. for (i=0;i<Count;++i)
  80. {
  81. s[0] = 0;
  82. p->Player->Get(p->Player,PLAYER_LIST_AUTOTITLE+i,s,sizeof(s));
  83. ListView_GetItemText(p->WndList,i,0,s2,256);
  84. if (tcscmp(s,s2)!=0)
  85. ListView_SetItemText(p->WndList,i,0,s);
  86. Length = -1;
  87. p->Player->Get(p->Player,PLAYER_LIST_LENGTH+i,&Length,sizeof(int));
  88. if (Length>=0)
  89. TickToString(s,TSIZEOF(s),Length,0,0,0);
  90. else
  91. s[0] = 0;
  92. ListView_GetItemText(p->WndList,i,1,s2,256);
  93. if (tcscmp(s,s2)!=0)
  94. ListView_SetItemText(p->WndList,i,1,s);
  95. s[0] = 0;
  96. p->Player->Get(p->Player,PLAYER_LIST_URL+i,s,sizeof(s));
  97. ListView_GetItemText(p->WndList,i,2,s2,256);
  98. if (tcscmp(s,s2)!=0)
  99. ListView_SetItemText(p->WndList,i,2,s);
  100. }
  101. }
  102. static int Enum(playlistwin* p, int* No, datadef* Param )
  103. {
  104. return NodeEnumTable(No,Param,Params);
  105. }
  106. static int Get(playlistwin* p,int No,void* Data,int Size)
  107. {
  108. int Result = ERR_INVALID_PARAM;
  109. switch (No)
  110. {
  111. case PLAYLIST_WIDTH_NAME: GETVALUE(p->DlgWidth[0],int); break;
  112. case PLAYLIST_WIDTH_LENGTH: GETVALUE(p->DlgWidth[1],int); break;
  113. case PLAYLIST_WIDTH_URL: GETVALUE(p->DlgWidth[2],int); break;
  114. }
  115. return Result;
  116. }
  117. static int Set(playlistwin* p,int No,const void* Data,int Size)
  118. {
  119. int Result = ERR_INVALID_PARAM;
  120. switch (No)
  121. {
  122. case PLAYLIST_WIDTH_NAME: SETVALUE(p->DlgWidth[0],int,ERR_NONE); break;
  123. case PLAYLIST_WIDTH_LENGTH: SETVALUE(p->DlgWidth[1],int,ERR_NONE); break;
  124. case PLAYLIST_WIDTH_URL: SETVALUE(p->DlgWidth[2],int,ERR_NONE); break;
  125. }
  126. return Result;
  127. }
  128. static int GetColWidth(playlistwin* p, int Index)
  129. {
  130. int cx = ListView_GetColumnWidth(p->WndList,Index);
  131. return WinPixelToUnitX(&p->Win,cx);
  132. }
  133. static void AddCol(playlistwin* p, int Index, const tchar_t* Name, int Width, int Format )
  134. {
  135. LVCOLUMN Col;
  136. Col.mask=LVCF_TEXT | LVCF_WIDTH | LVCF_FMT;
  137. Col.cx=WinUnitToPixelX(&p->Win,Width);
  138. Col.pszText=(tchar_t*)Name;
  139. Col.cchTextMax=tcslen(Name)+1;
  140. Col.fmt=Format;
  141. ListView_InsertColumn(p->WndList,Index,&Col);
  142. }
  143. static void CreateButtons(playlistwin* p)
  144. {
  145. if (QueryPlatform(PLATFORM_TYPENO) != TYPE_SMARTPHONE)
  146. {
  147. WinBitmap(&p->Win,IDB_PLAYLIST16,IDB_PLAYLIST32,5);
  148. WinAddButton(&p->Win,-1,-1,NULL,0);
  149. WinAddButton(&p->Win,PLAYLIST_ADD_FILES,2,NULL,0);
  150. WinAddButton(&p->Win,PLAYLIST_UP,0,NULL,0);
  151. WinAddButton(&p->Win,PLAYLIST_DOWN,1,NULL,0);
  152. WinAddButton(&p->Win,PLAYLIST_DELETE,3,NULL,0);
  153. //WinAddButton(&p->Win,PLAYLIST_PLAY,4,NULL,0);
  154. }
  155. }
  156. static void Resize(playlistwin* p)
  157. {
  158. RECT r;
  159. GetClientRect(p->Win.Wnd,&r);
  160. r.top += p->Win.ToolBarHeight;
  161. MoveWindow(p->WndList,r.left,r.top,r.right-r.left,r.bottom-r.top,0);
  162. }
  163. static int GetPos(playlistwin* p)
  164. {
  165. int n;
  166. for (n=0;n<ListView_GetItemCount(p->WndList);++n)
  167. if (ListView_GetItemState(p->WndList,n,LVIS_FOCUSED)==LVIS_FOCUSED)
  168. return n;
  169. return -1;
  170. }
  171. static int ListNotify(playlistwin* p,int Param,int Param2)
  172. {
  173. if (p->Win.Wnd)
  174. PostMessage(p->Win.Wnd,MSG_PLAYER2,0,0);
  175. return ERR_NONE;
  176. }
  177. static void BeginUpdate(playlistwin* p)
  178. {
  179. notify Notify;
  180. Notify.Func = NULL;
  181. Notify.This = 0;
  182. p->Player->Set(p->Player,PLAYER_LIST_NOTIFY,&Notify,sizeof(Notify));
  183. p->Pos = GetPos(p);
  184. p->InUpdate = 1;
  185. }
  186. static void EndUpdate(playlistwin* p)
  187. {
  188. int n;
  189. notify Notify;
  190. Notify.Func = ListNotify;
  191. Notify.This = p;
  192. p->Player->Set(p->Player,PLAYER_LIST_NOTIFY,&Notify,sizeof(Notify));
  193. UpdateList(p);
  194. for (n=0;n<ListView_GetItemCount(p->WndList);++n)
  195. ListView_SetItemState(p->WndList,n,n==p->Pos?LVIS_FOCUSED|LVIS_SELECTED:0,LVIS_FOCUSED|LVIS_SELECTED);
  196. if (p->Pos>=n || p->Pos<0)
  197. {
  198. ListView_SetItemState(p->WndList,0,LVIS_FOCUSED,LVIS_FOCUSED);
  199. p->Pos = 0;
  200. }
  201. ListView_EnsureVisible(p->WndList,p->Pos,TRUE);
  202. p->InUpdate = 0;
  203. }
  204. static void Play(playlistwin* p, int i)
  205. {
  206. bool_t b;
  207. node* Format;
  208. p->Player->Set(p->Player,PLAYER_LIST_CURRENT,&i,sizeof(i));
  209. // only play when loading succeeded
  210. if (p->Player->Get(p->Player,PLAYER_FORMAT,&Format,sizeof(Format)) == ERR_NONE && Format)
  211. {
  212. b = 1;
  213. p->Player->Set(p->Player,PLAYER_PLAY,&b,sizeof(b));
  214. }
  215. WinClose(&p->Win);
  216. }
  217. static bool_t Proc(playlistwin* p,int Msg, uint32_t wParam, uint32_t lParam, int* Result)
  218. {
  219. LPNMLISTVIEW Notify;
  220. int i,j,n;
  221. int Style;
  222. bool_t b;
  223. node* Node;
  224. switch (Msg)
  225. {
  226. case WM_KEYDOWN:
  227. if (wParam == VK_ESCAPE)
  228. WinClose(&p->Win);
  229. break;
  230. case MSG_PLAYER2:
  231. if (p->WndList)
  232. {
  233. p->InUpdate = 1;
  234. UpdateList(p);
  235. p->InUpdate = 0;
  236. }
  237. return 1;
  238. case WM_COMMAND:
  239. i = LOWORD(wParam);
  240. switch (i)
  241. {
  242. case PLAYLIST_DELETE:
  243. BeginUpdate(p);
  244. if (p->Player->Get(p->Player,PLAYER_LIST_COUNT,&j,sizeof(j))==ERR_NONE)
  245. {
  246. for (n=ListView_GetItemCount(p->WndList)-1;n>=0;--n)
  247. if (ListView_GetItemState(p->WndList,n,LVIS_SELECTED)==LVIS_SELECTED)
  248. {
  249. for (i=n;i<j-1;++i)
  250. p->Player->ListSwap(p->Player,i,i+1);
  251. --j;
  252. if (p->Pos>n || p->Pos>=j) --p->Pos;
  253. }
  254. p->Player->Set(p->Player,PLAYER_LIST_COUNT,&j,sizeof(j));
  255. }
  256. EndUpdate(p);
  257. break;
  258. case PLAYLIST_UP:
  259. BeginUpdate(p);
  260. if (p->Pos>0)
  261. {
  262. p->Player->ListSwap(p->Player,p->Pos,p->Pos-1);
  263. --p->Pos;
  264. }
  265. EndUpdate(p);
  266. break;
  267. case PLAYLIST_DOWN:
  268. BeginUpdate(p);
  269. if (p->Pos>=0 && p->Player->Get(p->Player,PLAYER_LIST_COUNT,&j,sizeof(j))==ERR_NONE && p->Pos<j-1)
  270. {
  271. p->Player->ListSwap(p->Player,p->Pos,p->Pos+1);
  272. ++p->Pos;
  273. }
  274. EndUpdate(p);
  275. break;
  276. case PLAYLIST_PLAY:
  277. Play(p,GetPos(p));
  278. break;
  279. case PLAYLIST_SORTBYNAME:
  280. BeginUpdate(p);
  281. if (p->Player->Get(p->Player,PLAYER_LIST_COUNT,&j,sizeof(j))==ERR_NONE)
  282. {
  283. // bubble sort sucks :)
  284. do
  285. {
  286. b = 0;
  287. for (i=0;i<j-1;++i)
  288. {
  289. tchar_t URL1[MAXPATH];
  290. tchar_t URL2[MAXPATH];
  291. if (p->Player->Get(p->Player,PLAYER_LIST_URL+i,URL1,sizeof(URL1))==ERR_NONE &&
  292. p->Player->Get(p->Player,PLAYER_LIST_URL+i+1,URL2,sizeof(URL2))==ERR_NONE &&
  293. tcsicmp(URL1,URL2)>0)
  294. {
  295. if (p->Pos == i) 
  296. p->Pos = i+1;
  297. else
  298. if (p->Pos == i+1)
  299. p->Pos = i;
  300. p->Player->ListSwap(p->Player,i,i+1);
  301. b = 1;
  302. }
  303. }
  304. }
  305. while (b);
  306. }
  307. EndUpdate(p);
  308. break;
  309. case PLAYLIST_DELETE_ALL:
  310. BeginUpdate(p);
  311. i = 0;
  312. p->Player->Set(p->Player,PLAYER_LIST_COUNT,&i,sizeof(i));
  313. EndUpdate(p);
  314. break;
  315. case PLAYLIST_SAVE:
  316. BeginUpdate(p);
  317. Node = NodeCreate(OPENFILE_ID);
  318. if (Node)
  319. {
  320. i = OPENFLAG_SINGLE | OPENFLAG_SAVE;
  321. Node->Set(Node,OPENFILE_FLAGS,&i,sizeof(i));
  322. i = PLAYLIST_CLASS;
  323. Node->Set(Node,OPENFILE_CLASS,&i,sizeof(i));
  324. ((win*)Node)->Popup((win*)Node,&p->Win);
  325. NodeDelete(Node);
  326. }
  327. EndUpdate(p);
  328. break;
  329. case PLAYLIST_LOAD:
  330. BeginUpdate(p);
  331. Node = NodeCreate(OPENFILE_ID);
  332. if (Node)
  333. {
  334. i = OPENFLAG_SINGLE;
  335. Node->Set(Node,OPENFILE_FLAGS,&i,sizeof(i));
  336. i = PLAYLIST_CLASS;
  337. Node->Set(Node,OPENFILE_CLASS,&i,sizeof(i));
  338. i = ((win*)Node)->Popup((win*)Node,&p->Win);
  339. NodeDelete(Node);
  340. if (i==2)
  341. {
  342. UpdateWindow(p->Win.Wnd);
  343. i=0;
  344. p->Player->Set(p->Player,PLAYER_LIST_CURRIDX,&i,sizeof(i));
  345. }
  346. }
  347. p->Pos = -1;
  348. p->Player->Get(p->Player,PLAYER_LIST_CURRENT,&p->Pos,sizeof(int));
  349. EndUpdate(p);
  350. break;
  351. case PLAYLIST_ADD_FILES:
  352. BeginUpdate(p);
  353. Node = NodeCreate(OPENFILE_ID);
  354. if (Node)
  355. {
  356. i = OPENFLAG_ADD;
  357. Node->Set(Node,OPENFILE_FLAGS,&i,sizeof(i));
  358. i = MEDIA_CLASS;
  359. Node->Set(Node,OPENFILE_CLASS,&i,sizeof(i));
  360. ((win*)Node)->Popup((win*)Node,&p->Win);
  361. NodeDelete(Node);
  362. }
  363. p->Pos = -1;
  364. p->Player->Get(p->Player,PLAYER_LIST_CURRENT,&p->Pos,sizeof(int));
  365. EndUpdate(p);
  366. break;
  367. }
  368. break;
  369. case WM_CREATE:
  370. p->InUpdate = 1;
  371. p->ThreadId = GetCurrentThreadId();
  372. p->Player = (player*)Context()->Player;
  373. p->Pos = -1;
  374. p->Player->Get(p->Player,PLAYER_LIST_CURRENT,&p->Pos,sizeof(int));
  375. Style = WS_TABSTOP|WS_VISIBLE|WS_CHILD|WS_VSCROLL|WS_HSCROLL|LVS_REPORT|LVS_SHOWSELALWAYS;
  376. if (p->Win.ScreenWidth < 130)
  377. Style |= LVS_NOCOLUMNHEADER;
  378. p->WndList = CreateWindow(T("SysListView32"), NULL, Style,
  379. 0,0,20,20, p->Win.Wnd, NULL, p->Win.Module, NULL);
  380. ListView_SetExtendedListViewStyle(p->WndList,LVS_EX_FULLROWSELECT);
  381. AddCol(p,0,LangStr(PLAYLIST_ID,PLAYLIST_LABEL_NAME),max(15,p->DlgWidth[0]),LVCFMT_LEFT);
  382. AddCol(p,1,LangStr(PLAYLIST_ID,PLAYLIST_LABEL_LENGTH),max(15,p->DlgWidth[1]),LVCFMT_LEFT);
  383. AddCol(p,2,LangStr(PLAYLIST_ID,PLAYLIST_LABEL_URL),max(15,p->DlgWidth[2]),LVCFMT_LEFT);
  384. CreateButtons(p);
  385. Resize(p);
  386. EndUpdate(p);
  387. break;
  388. case WM_SETFOCUS:
  389. SetFocus(p->WndList);
  390. break;
  391. case WM_DESTROY:
  392. BeginUpdate(p);
  393. p->DlgWidth[0] = GetColWidth(p,0);
  394. p->DlgWidth[1] = GetColWidth(p,1);
  395. p->DlgWidth[2] = GetColWidth(p,2);
  396. p->ThreadId = 0;
  397. p->WndList = NULL;
  398. break;
  399. case WM_SIZE:
  400. Resize(p);
  401. break;
  402. case WM_NOTIFY:
  403. Notify = (LPNMLISTVIEW) lParam;
  404. if (Notify->hdr.hwndFrom == p->WndList && !p->InUpdate)
  405. {
  406. if (Notify->hdr.code==LVN_ITEMACTIVATE)
  407. Play(p,Notify->iItem);
  408. if (Notify->hdr.code==LVN_KEYDOWN && ((LPNMLVKEYDOWN)lParam)->wVKey == VK_ESCAPE)
  409. WinClose(&p->Win);
  410. }
  411. break;
  412. }
  413. return 0;
  414. }
  415. static menudef MenuDef[] =
  416. {
  417. { 0,PLATFORM_ID, PLATFORM_DONE },
  418. { 0,PLAYLIST_ID, PLAYLIST_FILE },
  419. { 1,PLAYLIST_ID, PLAYLIST_ADD_FILES },
  420. { 1,-1,-1 },
  421. { 1,PLAYLIST_ID, PLAYLIST_PLAY },
  422. { 1,-1,-1 },
  423. { 1,PLAYLIST_ID, PLAYLIST_DELETE },
  424. { 1,PLAYLIST_ID, PLAYLIST_DELETE_ALL },
  425. { 1,-1,-1 },
  426. { 1,PLAYLIST_ID, PLAYLIST_SORTBYNAME },
  427. { 1,PLAYLIST_ID, PLAYLIST_UP },
  428. { 1,PLAYLIST_ID, PLAYLIST_DOWN },
  429. { 1,-1,-1 },
  430. { 1,PLAYLIST_ID, PLAYLIST_LOAD },
  431. { 1,PLAYLIST_ID, PLAYLIST_SAVE },
  432. MENUDEF_END
  433. };
  434. WINCREATE(PlayList)
  435. static int Create(playlistwin* p)
  436. {
  437. PlayListCreate(&p->Win);
  438. if (!p->Win.Smartphone)
  439. p->DlgWidth[0] = 145;
  440. else
  441. p->DlgWidth[0] = 92;
  442. p->DlgWidth[1] = 40;
  443. p->DlgWidth[2] = 200;
  444. p->Win.WinWidth = 180;
  445. p->Win.WinHeight = 240;
  446. p->Win.MenuDef = MenuDef;
  447. p->Win.Proc = Proc;
  448. p->Win.Node.Enum = Enum;
  449. p->Win.Node.Get = Get;
  450. p->Win.Node.Set = Set;
  451. return ERR_NONE;
  452. }
  453. static void Delete(playlistwin* p)
  454. {
  455. #ifdef REGISTRY_GLOBAL
  456. NodeRegSave(&p->Win.Node);
  457. #endif
  458. }
  459. static const nodedef PlayListWin =
  460. {
  461. sizeof(playlistwin)|CF_GLOBAL,
  462. PLAYLIST_ID,
  463. WIN_CLASS,
  464. PRI_DEFAULT,
  465. (nodecreate)Create,
  466. (nodedelete)Delete,
  467. };
  468. void PlaylistWin_Init()
  469. {
  470. NodeRegisterClass(&PlayListWin);
  471. }
  472. void PlaylistWin_Done()
  473. {
  474. NodeUnRegisterClass(PLAYLIST_ID);
  475. }
  476. #endif