view.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. #include "resource.h"
  2. #include "main.h"
  3. #include "api.h"
  4. #include "../nu/listview.h"
  5. #include "../nu/ChildSizer.h"
  6. #include "../nu/DialogSkinner.h"
  7. #include "impl_playlist.h"
  8. #include "../nu/SendTo.h"
  9. #include <strsafe.h>
  10. static ChildWndResizeItem view_rlist[] =
  11. {
  12. { IDC_PLAYLIST, ResizeBottom | ResizeRight},
  13. { IDC_PLAY, DockToBottom},
  14. { IDC_ENQUEUE, DockToBottom},
  15. { IDC_SAVE, DockToBottom},
  16. { IDC_SENDTO, DockToBottom},
  17. };
  18. W_ListView playlist_list;
  19. Playlist currentPlaylist;
  20. int playlist_skin;
  21. static SendToMenu sendTo(plugin);
  22. static void PlaySelection(int enqueue, int is_all)
  23. {
  24. if (!enqueue)
  25. SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_DELETE);
  26. int numTracks = playlist_list.GetCount();
  27. for (int i = 0;i < numTracks;i++)
  28. {
  29. if (is_all || playlist_list.GetSelected(i))
  30. {
  31. if (currentPlaylist.IsCached(i))
  32. {
  33. enqueueFileWithMetaStructW s;
  34. s.filename = currentPlaylist.ItemName(i);
  35. s.title = currentPlaylist.ItemTitle(i);
  36. s.length = currentPlaylist.GetItemLengthMilliseconds(i) / 1000;
  37. SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_PLAYFILEW);
  38. }
  39. else
  40. {
  41. enqueueFileWithMetaStructW s;
  42. s.filename = currentPlaylist.ItemName(i);
  43. s.title = 0;
  44. s.length = 0;
  45. SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_PLAYFILEW);
  46. }
  47. }
  48. }
  49. if (!enqueue)
  50. {
  51. if (is_all)
  52. {
  53. int pos = playlist_list.GetNextSelected(-1);
  54. if (pos != -1)
  55. {
  56. SendMessage(plugin.hwndWinampParent, WM_WA_IPC, pos, IPC_SETPLAYLISTPOS);
  57. SendMessage(plugin.hwndWinampParent, WM_COMMAND, 40047, 0); // stop button, literally
  58. SendMessage(plugin.hwndWinampParent, WM_COMMAND, 40045, 0); // play button, literally
  59. return ;
  60. }
  61. }
  62. SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_STARTPLAY);
  63. }
  64. /*
  65. int cnt=0;
  66. int l=PlayList_getlength();
  67. int foo_all=0; // all but play the only selected
  68. int foo_selected=-1;
  69. if (g_config->ReadInt("plplaymode",1)||is_all)
  70. {
  71. int selcnt=0;
  72. for(int i=0;i<l;i++)
  73. {
  74. if(PlayList_getselect(i)) selcnt++;
  75. }
  76. if ((selcnt == 1 && !enqueue) || selcnt == 0)
  77. {
  78. foo_all=-1;
  79. }
  80. }
  81. */
  82. }
  83. static void playlist_DisplayChange()
  84. {
  85. playlist_list.SetTextColors(dialogSkinner.Color(WADLG_ITEMFG), dialogSkinner.Color(WADLG_ITEMBG));
  86. ListView_SetBkColor(playlist_list.getwnd(), dialogSkinner.Color(WADLG_ITEMBG));
  87. playlist_list.SetFont(dialogSkinner.GetFont());
  88. }
  89. static BOOL playlist_GetDisplayInfo(NMLVDISPINFO *lpdi)
  90. {
  91. size_t item = lpdi->item.iItem;
  92. if (item < 0 || item >= currentPlaylist.GetNumItems()) return 0;
  93. if (lpdi->item.mask & LVIF_TEXT)
  94. {
  95. switch (lpdi->item.iSubItem)
  96. {
  97. case 0:
  98. {
  99. bool cached = currentPlaylist.IsCached(item);
  100. if (!cached)
  101. {
  102. wchar_t title[400];
  103. int length;
  104. mediaLibrary.GetFileInfo(currentPlaylist.ItemName(item), title, 400, &length);
  105. if (length == 0)
  106. currentPlaylist.SetItemLengthMilliseconds(item, -1000);
  107. else
  108. currentPlaylist.SetItemLengthMilliseconds(item, length*1000);
  109. currentPlaylist.SetItemTitle(item, title);
  110. }
  111. // CUT: currentPlaylist.GetItemTitle(item, lpdi->item.pszText, lpdi->item.cchTextMax);
  112. StringCchPrintf(lpdi->item.pszText, lpdi->item.cchTextMax, L"%d. %s", item + 1, currentPlaylist.ItemTitle(item));
  113. }
  114. break;
  115. case 1:
  116. {
  117. if (currentPlaylist.GetItemLengthMilliseconds(item) == 0) // if the length is 0, then we'll re-read it
  118. {
  119. wchar_t title[400];
  120. int length;
  121. mediaLibrary.GetFileInfo(currentPlaylist.ItemName(item), title, 400, &length);
  122. if (length == 0)
  123. currentPlaylist.SetItemLengthMilliseconds(item, -1000);
  124. else
  125. {
  126. currentPlaylist.SetItemLengthMilliseconds(item, length*1000);
  127. // currentPlaylist.SetItemTitle(item, AutoWide(title));
  128. }
  129. }
  130. int length = currentPlaylist.GetItemLengthMilliseconds(item) / 1000;
  131. if (length <= 0)
  132. lpdi->item.pszText[0] = 0;
  133. else
  134. StringCchPrintf(lpdi->item.pszText, lpdi->item.cchTextMax, L"%d:%02d", length / 60, length % 60);
  135. }
  136. break;
  137. }
  138. }
  139. return 0;
  140. }
  141. static INT_PTR playlist_Notify(HWND hwndDlg, WPARAM wParam, LPARAM lParam)
  142. {
  143. LPNMHDR l = (LPNMHDR)lParam;
  144. if (l->idFrom == IDC_PLAYLIST)
  145. {
  146. switch (l->code)
  147. {
  148. /*
  149. case NM_RETURN:
  150. if (!(GetAsyncKeyState(VK_SHIFT)&0x8000))
  151. PlaySelection(g_config->ReadInt("enqueuedef", 0), g_config->ReadInt("plplaymode", 1));
  152. else
  153. PlaySelection(!g_config->ReadInt("enqueuedef", 0), 0);
  154. break;
  155. case NM_DBLCLK:
  156. PlaySelection(g_config->ReadInt("enqueuedef", 0), g_config->ReadInt("plplaymode", 1));
  157. break;*/
  158. case LVN_GETDISPINFO:
  159. return playlist_GetDisplayInfo((NMLVDISPINFO*) lParam);
  160. /*case LVN_BEGINDRAG:
  161. we_are_drag_and_dropping = 1;
  162. SetCapture(hwndDlg);
  163. break;
  164. */
  165. /*
  166. case LVN_ITEMCHANGED:
  167. case LVN_ODSTATECHANGED:
  168. UpdatePlaylistTime(hwndDlg);
  169. break;
  170. */
  171. /*
  172. case LVN_KEYDOWN:
  173. {
  174. LPNMLVKEYDOWN pnkd = (LPNMLVKEYDOWN) lParam;
  175. switch (pnkd->wVKey)
  176. {
  177. case VK_DELETE:
  178. if (GetAsyncKeyState(VK_CONTROL)&0x8000)
  179. Playlist_DeleteSelected(0);
  180. else
  181. Playlist_DeleteSelected(1);
  182. break;
  183. case '3':
  184. if (GetAsyncKeyState(VK_MENU)&0x8000)
  185. TagEditor(hwndDlg);
  186. break;
  187. case 'A':
  188. if (GetAsyncKeyState(VK_CONTROL)&0x8000)
  189. playlist_list.SelectAll();
  190. break;
  191. case 'I':
  192. if (GetAsyncKeyState(VK_CONTROL)&0x8000)
  193. playlist_list.InvertSelection();
  194. break;
  195. case 'L':
  196. if (GetAsyncKeyState(VK_CONTROL)&0x8000)
  197. CurrentPlaylist_AddLocation(hwndDlg);
  198. else if (GetAsyncKeyState(VK_SHIFT)&0x8000)
  199. CurrentPlaylist_AddDirectory(hwndDlg);
  200. else
  201. CurrentPlaylist_AddFiles(hwndDlg);
  202. SyncPlaylist();
  203. break;
  204. case 'R':
  205. if (GetAsyncKeyState(VK_CONTROL)&0x8000)
  206. {
  207. if (GetAsyncKeyState(VK_SHIFT)&0x8000)
  208. AGAVE_API_PLAYLISTMANAGER->Randomize(&currentPlaylist);
  209. else
  210. AGAVE_API_PLAYLISTMANAGER->Reverse(&currentPlaylist);
  211. playlist_list.RefreshAll();
  212. }
  213. break;
  214. case 'E':
  215. if (GetAsyncKeyState(VK_CONTROL)&0x8000)
  216. {
  217. if (GetAsyncKeyState(VK_MENU)&0x8000)
  218. Playlist_ResetSelected();
  219. else
  220. EditEntry(l->hwndFrom);
  221. }
  222. break;
  223. }
  224. }
  225. break;
  226. */
  227. }
  228. }
  229. return 0;
  230. }
  231. static wchar_t *BuildFilenameList(int is_all)
  232. {
  233. wchar_t filename[MAX_PATH] = {0};
  234. size_t len = 200;
  235. wchar_t *str = (wchar_t *)malloc(len*sizeof(wchar_t));
  236. size_t sofar = 0;
  237. int numTracks = playlist_list.GetCount();
  238. for (int i = 0;i < numTracks;i++)
  239. {
  240. if (is_all || playlist_list.GetSelected(i))
  241. {
  242. if (currentPlaylist.GetItem(i, filename, MAX_PATH))
  243. {
  244. size_t filenameLen = wcslen(filename);
  245. if ((filenameLen + sofar) > len)
  246. {
  247. size_t newLen = filenameLen + sofar + 32; // add some cushion
  248. wchar_t *newStr = (wchar_t *)malloc(newLen*sizeof(wchar_t));
  249. memcpy(newStr, str, sofar*sizeof(wchar_t));
  250. len = newLen;
  251. free(str);
  252. str = newStr;
  253. }
  254. StringCchCopyW(str + sofar, filenameLen, filename);
  255. sofar += filenameLen + 1;
  256. }
  257. }
  258. }
  259. *(str + sofar) = 0;
  260. return str;
  261. }
  262. INT_PTR CALLBACK ViewProcedure(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
  263. {
  264. INT_PTR a = dialogSkinner.Handle(hwndDlg, msg, wParam, lParam);
  265. if (a)
  266. return a;
  267. switch (msg)
  268. {
  269. case WM_INITMENUPOPUP:
  270. sendTo.InitPopupMenu(wParam);
  271. return 0;
  272. case WM_INITDIALOG:
  273. childSizer.Init(hwndDlg, view_rlist, sizeof(view_rlist) / sizeof(view_rlist[0]));
  274. playlist_list.setwnd(GetDlgItem(hwndDlg, IDC_PLAYLIST));
  275. playlist_skin = mediaLibrary.SkinList(GetDlgItem(hwndDlg, IDC_PLAYLIST));
  276. playlist_list.AddCol(L"Song",200);
  277. playlist_list.AddCol(L"Length",100);
  278. playlist_list.JustifyColumn(1, LVCFMT_RIGHT);
  279. playlist_DisplayChange();
  280. playlist_list.SetVirtualCount(currentPlaylist.GetNumItems());
  281. break;
  282. case WM_PAINT:
  283. {
  284. int tab[] = {IDC_PLAYLIST|DCW_SUNKENBORDER};
  285. dialogSkinner.Draw(hwndDlg,tab,1);
  286. }
  287. return 0;
  288. case WM_SIZE:
  289. if (wParam != SIZE_MINIMIZED)
  290. childSizer.Resize(hwndDlg, view_rlist, sizeof(view_rlist) / sizeof(view_rlist[0]));
  291. break;
  292. case WM_COMMAND:
  293. switch (LOWORD(wParam))
  294. {
  295. case IDC_PLAY:
  296. if (playlist_list.GetSelectedCount() > 0)
  297. PlaySelection(0, 0/*g_config->ReadInt("plplaymode", 1)*/);
  298. else
  299. PlaySelection(0, 1);
  300. break;
  301. case IDC_ENQUEUE:
  302. if (playlist_list.GetSelectedCount() > 0)
  303. PlaySelection(0, 0);
  304. else
  305. PlaySelection(1, 0);
  306. break;
  307. case IDC_SAVE:
  308. break;
  309. case IDC_SENDTO:
  310. {
  311. HMENU blah = CreatePopupMenu();
  312. RECT r;
  313. GetWindowRect(GetDlgItem(hwndDlg, IDC_SENDTO), &r);
  314. sendTo.AddHere(hwndDlg, blah, ML_TYPE_FILENAMESW);
  315. int x = TrackPopupMenu(blah, TPM_RIGHTBUTTON | TPM_LEFTBUTTON | TPM_BOTTOMALIGN | TPM_LEFTALIGN | TPM_RETURNCMD, r.left, r.top, 0, hwndDlg, NULL);
  316. if (sendTo.WasClicked(x))
  317. {
  318. int is_all = playlist_list.GetSelectedCount() == 0;
  319. wchar_t *names = BuildFilenameList(is_all);
  320. sendTo.SendFilenames(names);
  321. free(names);
  322. }
  323. sendTo.Cleanup();
  324. }
  325. break;
  326. }
  327. break;
  328. case WM_DISPLAYCHANGE: playlist_DisplayChange(); return 0;
  329. case WM_NOTIFY: return playlist_Notify(hwndDlg, wParam, lParam);
  330. case WM_DESTROY:
  331. mediaLibrary.UnskinList(playlist_skin);
  332. break;
  333. }
  334. return 0;
  335. }