cmdbar_data.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. #include "main.h"
  2. #include <windowsx.h>
  3. #include "./resource.h"
  4. #include "./commandbar.h"
  5. #include <shlwapi.h>
  6. #include <strsafe.h>
  7. static HMLIMGLST hmlilButton = NULL;
  8. static LPCTSTR GetImageTagStr(INT resId)
  9. {
  10. switch(resId)
  11. {
  12. case IDB_PLAY_NORMAL: return TEXT("button.play");
  13. case IDB_PLAY_HIGHLIGHTED: return TEXT("button.play.highlighted");
  14. case IDB_PLAY_PRESSED: return TEXT("button.play.pressed");
  15. case IDB_PLAY_DISABLED: return TEXT("button.play.disabled");
  16. case IDB_ENQUEUE_NORMAL: return TEXT("button.enqueue");
  17. case IDB_ENQUEUE_HIGHLIGHTED: return TEXT("button.enqueue.highlighted");
  18. case IDB_ENQUEUE_PRESSED: return TEXT("button.enqueue.pressed");
  19. case IDB_ENQUEUE_DISABLED: return TEXT("button.enqueue.disabled");
  20. case IDB_EJECT2_NORMAL: return TEXT("button.eject");
  21. case IDB_EJECT2_HIGHLIGHTED: return TEXT("button.eject.highlighted");
  22. case IDB_EJECT2_PRESSED: return TEXT("button.eject.pressed");
  23. case IDB_EJECT2_DISABLED: return TEXT("button.eject.disabled");
  24. }
  25. return NULL;
  26. }
  27. static HMLIMGLST DataCmdBar_CreateImageList()
  28. {
  29. HMLIMGLST hmlil;
  30. MLIMAGELISTCREATE mlilCreate;
  31. MLIMAGESOURCE mlis;
  32. MLIMAGELISTITEM mlilItem;
  33. mlilCreate.cx = g_view_metaconf->ReadIntEx(TEXT("artwork"), TEXT("button.icon.cx"), 12);
  34. mlilCreate.cy = g_view_metaconf->ReadIntEx(TEXT("artwork"), TEXT("button.icon.cy"), 12);
  35. mlilCreate.cInitial = 12;
  36. mlilCreate.cGrow = 3;
  37. mlilCreate.cCacheSize = 4;
  38. mlilCreate.flags = MLILC_COLOR32;
  39. hmlil = MLImageList_Create(plugin.hwndLibraryParent, &mlilCreate);
  40. if (NULL == hmlil) return NULL;
  41. ZeroMemory(&mlilItem, sizeof(MLIMAGELISTITEM));
  42. mlilItem.cbSize = sizeof(MLIMAGELISTITEM);
  43. mlilItem.hmlil = hmlil;
  44. mlilItem.filterUID = MLIF_BUTTONBLENDPLUSCOLOR_UID;
  45. mlilItem.pmlImgSource = &mlis;
  46. ZeroMemory(&mlis, sizeof(MLIMAGESOURCE));
  47. mlis.cbSize = sizeof(MLIMAGESOURCE);
  48. mlis.type = SRC_TYPE_PNG;
  49. mlis.hInst = plugin.hDllInstance;
  50. INT imageList[] =
  51. { IDB_PLAY_NORMAL, IDB_PLAY_PRESSED, IDB_PLAY_HIGHLIGHTED, IDB_PLAY_DISABLED,
  52. IDB_ENQUEUE_NORMAL, IDB_ENQUEUE_PRESSED, IDB_ENQUEUE_HIGHLIGHTED, IDB_ENQUEUE_DISABLED,
  53. IDB_EJECT2_NORMAL, IDB_EJECT2_PRESSED, IDB_EJECT2_HIGHLIGHTED, IDB_EJECT2_DISABLED,
  54. };
  55. TCHAR szResource[MAX_PATH] = {0}, szPath[MAX_PATH] = {0}, szFullPath[MAX_PATH] = {0};
  56. g_view_metaconf->ReadCchStringEx(szPath, ARRAYSIZE(szPath), TEXT("artwork"), TEXT("path"), NULL);
  57. for(int i = 0; i < sizeof(imageList)/sizeof(imageList[0]); i++)
  58. {
  59. mlilItem.nTag = imageList[i];
  60. g_view_metaconf->ReadCchStringEx(szResource, ARRAYSIZE(szResource), TEXT("artwork"), GetImageTagStr(imageList[i]), NULL);
  61. if (TEXT('\0') != szResource[0])
  62. {
  63. PathCombine(szFullPath, szPath, szResource);
  64. mlis.lpszName = szFullPath;
  65. mlis.flags |= ISF_LOADFROMFILE;
  66. }
  67. else
  68. {
  69. mlis.lpszName = MAKEINTRESOURCE(imageList[i]);
  70. mlis.flags &= ~ISF_LOADFROMFILE;
  71. }
  72. MLImageList_Add(plugin.hwndLibraryParent, &mlilItem);
  73. }
  74. return hmlil;
  75. }
  76. static HMLIMGLST DataCmdBar_CreateDropDownImageList(HMENU hMenu)
  77. {
  78. HMLIMGLST hmlil;
  79. MLIMAGELISTCREATE mlilCreate;
  80. MLIMAGESOURCE mlis;
  81. if (!hMenu) return NULL;
  82. mlilCreate.cx = 16;
  83. mlilCreate.cy = 16;
  84. mlilCreate.cInitial = 2;
  85. mlilCreate.cGrow = 1;
  86. mlilCreate.cCacheSize = 3;
  87. mlilCreate.flags = MLILC_COLOR32;
  88. hmlil = MLImageList_Create(plugin.hwndLibraryParent, &mlilCreate);
  89. if (NULL == hmlil) return NULL;
  90. ZeroMemory(&mlis, sizeof(MLIMAGESOURCE));
  91. mlis.cbSize = sizeof(MLIMAGESOURCE);
  92. mlis.type = SRC_TYPE_PNG;
  93. mlis.hInst = plugin.hDllInstance;
  94. INT imageList[] = { IDB_PLAY_MENU, IDB_ENQUEUE_MENU, };
  95. MENUITEMINFOW mii = { sizeof(MENUITEMINFOW), };
  96. mii.fMask = MIIM_ID;
  97. for(int i = 0; i < sizeof(imageList)/sizeof(imageList[0]); i++)
  98. {
  99. if (GetMenuItemInfoW(hMenu, i, TRUE, &mii))
  100. {
  101. mlis.lpszName = MAKEINTRESOURCEW(imageList[i]);
  102. MLImageList_Add2(plugin.hwndLibraryParent, hmlil, MLIF_FILTER1_UID, &mlis, mii.wID);
  103. }
  104. }
  105. return hmlil;
  106. }
  107. static void DataCmdBar_SetButtonImages(HWND hButton, HMLIMGLST hmlil, INT normal, INT hover, INT pressed, INT disabled)
  108. {
  109. MLBUTTONIMAGELIST bil;
  110. MLIMAGELISTTAG t;
  111. bil.hmlil = hmlil;
  112. t.hmlil = bil.hmlil;
  113. t.nTag = normal;
  114. bil.normalIndex = (MLImageList_GetIndexFromTag(plugin.hwndLibraryParent, &t)) ? t.mlilIndex : -1;
  115. if (disabled == normal) bil.disabledIndex = bil.normalIndex;
  116. else
  117. {
  118. t.nTag = disabled;
  119. bil.disabledIndex = (MLImageList_GetIndexFromTag(plugin.hwndLibraryParent, &t)) ? t.mlilIndex : bil.normalIndex;
  120. }
  121. if (hover == normal) bil.hoverIndex = bil.normalIndex;
  122. else if (hover == disabled) bil.hoverIndex = bil.disabledIndex;
  123. else
  124. {
  125. t.nTag = hover;
  126. bil.hoverIndex = (MLImageList_GetIndexFromTag(plugin.hwndLibraryParent, &t)) ? t.mlilIndex : bil.normalIndex;
  127. }
  128. if (pressed == normal) bil.pressedIndex = bil.normalIndex;
  129. else if (pressed == disabled) bil.pressedIndex = bil.disabledIndex;
  130. else if (pressed == hover) bil.pressedIndex = bil.hoverIndex;
  131. else
  132. {
  133. t.nTag = pressed;
  134. bil.pressedIndex = (MLImageList_GetIndexFromTag(plugin.hwndLibraryParent, &t)) ? t.mlilIndex : bil.normalIndex;
  135. }
  136. SENDMLIPC(hButton, ML_IPC_SKINNEDBUTTON_SETIMAGELIST, (LPARAM)&bil);
  137. }
  138. static void PlayEx_Initialize(HWND hdlg)
  139. {
  140. HWND hButton = GetDlgItem(hdlg, IDC_BTN_PLAYEX);
  141. if (!hButton) return;
  142. HWND hFileView = (HWND)CommandBar_GetData(hdlg);
  143. if (NULL == hFileView) return;
  144. HMENU hMenu = FileView_GetMenu(hFileView, FVMENU_PLAY);
  145. if (!hMenu) return;
  146. BOOL bPlay = (!hFileView || 0 == (FVS_ENQUEUE & FileView_GetStyle(hFileView)));
  147. WCHAR szBuffer[256] = {0};
  148. MENUITEMINFOW mii = { sizeof(MENUITEMINFOW), };
  149. mii.fMask = MIIM_STRING;
  150. mii.dwTypeData = szBuffer;
  151. mii.cch = sizeof(szBuffer)/sizeof(szBuffer[0]);
  152. if (GetMenuItemInfoW(hMenu, (bPlay) ? 0 : 1, TRUE, &mii))
  153. {
  154. while(mii.cch && L'\t' != szBuffer[mii.cch]) mii.cch--;
  155. if (mii.cch > 0) szBuffer[mii.cch] = L'\0';
  156. SetWindowTextW(hButton, szBuffer);
  157. }
  158. if (bPlay)
  159. {
  160. DataCmdBar_SetButtonImages(hButton, hmlilButton, IDB_PLAY_NORMAL,
  161. IDB_PLAY_PRESSED, IDB_PLAY_HIGHLIGHTED, IDB_PLAY_DISABLED);
  162. }
  163. else
  164. {
  165. DataCmdBar_SetButtonImages(hButton, hmlilButton, IDB_ENQUEUE_NORMAL,
  166. IDB_ENQUEUE_PRESSED, IDB_ENQUEUE_HIGHLIGHTED, IDB_ENQUEUE_DISABLED);
  167. }
  168. }
  169. static void DataCmdBar_UpdateControls(HWND hdlg, BOOL bRedraw)
  170. {
  171. INT buttonList[] = { IDC_BTN_PLAYEX, IDC_BTN_COPY, };
  172. HDWP hdwp;
  173. DWORD flags, size;
  174. INT w;
  175. flags = SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | ((bRedraw) ? 0 : SWP_NOREDRAW);
  176. hdwp = BeginDeferWindowPos(sizeof(buttonList)/sizeof(buttonList[0]));
  177. if (!hdwp) return;
  178. for(int i =0; i < sizeof(buttonList)/sizeof(buttonList[0]); i++)
  179. {
  180. HWND hctrl = GetDlgItem(hdlg, buttonList[i]);
  181. if (NULL != hctrl)
  182. {
  183. size = 0;
  184. switch(buttonList[i])
  185. {
  186. case IDC_BTN_PLAYEX:
  187. {
  188. HWND hFileView = (HWND)CommandBar_GetData(hdlg);
  189. if (NULL == hFileView) return;
  190. HMENU hMenu = FileView_GetMenu(hFileView, FVMENU_PLAY);
  191. if (hMenu)
  192. {
  193. WCHAR szText[256] = {0};
  194. INT count = GetMenuItemCount(hMenu);
  195. MENUITEMINFO mii = {0};
  196. mii.cbSize = sizeof(MENUITEMINFO);
  197. mii.fMask = MIIM_STRING;
  198. mii.dwTypeData = szText;
  199. w = 0;
  200. for (int i = 0; i < count; i++)
  201. {
  202. mii.cch = sizeof(szText)/sizeof(szText[0]);
  203. if (GetMenuItemInfo(hMenu, i, TRUE, &mii))
  204. {
  205. while(mii.cch && L'\t' != szText[mii.cch]) mii.cch--;
  206. if (mii.cch > 0) szText[mii.cch] = L'\0';
  207. size = MLSkinnedButton_GetIdealSize(hctrl, szText);
  208. if (w < LOWORD(size)) w = LOWORD(size);
  209. }
  210. }
  211. size = MAKELONG(w + 8, HIWORD(size));
  212. }
  213. }
  214. break;
  215. default:
  216. size = MLSkinnedButton_GetIdealSize(hctrl, NULL);
  217. break;
  218. }
  219. INT width = LOWORD(size), height = HIWORD(size);
  220. if (width < 82) width = 82;
  221. if (height < 14) height = 14;
  222. hdwp = DeferWindowPos(hdwp, hctrl, NULL, 0, 0, width, height, flags);
  223. }
  224. }
  225. EndDeferWindowPos(hdwp);
  226. SetWindowPos(hdlg, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE |
  227. SWP_NOZORDER | SWP_FRAMECHANGED | ((bRedraw) ? 0 : SWP_NOREDRAW));
  228. }
  229. static BOOL DataCmdBar_OnInitDialog(HWND hdlg, HWND hwndFocus, LPARAM lParam)
  230. {
  231. MLSKINWINDOW sw;
  232. sw.skinType = SKINNEDWND_TYPE_AUTO;
  233. sw.style = SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWS_USESKINFONT;
  234. sw.hwndToSkin = hdlg;
  235. MLSkinWindow(plugin.hwndLibraryParent, &sw);
  236. sw.hwndToSkin = GetDlgItem(hdlg, IDC_BTN_EJECT);
  237. MLSkinWindow(plugin.hwndLibraryParent, &sw);
  238. sw.style |= SWBS_SPLITBUTTON;
  239. sw.hwndToSkin = GetDlgItem(hdlg, IDC_BTN_PLAYEX);
  240. MLSkinWindow(plugin.hwndLibraryParent, &sw);
  241. sw.style = SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWS_USESKINFONT;
  242. sw.hwndToSkin = GetDlgItem(hdlg, IDC_BTN_COPY);
  243. MLSkinWindow(plugin.hwndLibraryParent, &sw);
  244. sw.skinType = SKINNEDWND_TYPE_STATIC;
  245. sw.style = SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWS_USESKINFONT;
  246. sw.hwndToSkin = GetDlgItem(hdlg, IDC_LBL_STATUS);
  247. MLSkinWindow(plugin.hwndLibraryParent, &sw);
  248. hmlilButton = DataCmdBar_CreateImageList();
  249. PlayEx_Initialize(hdlg);
  250. DataCmdBar_SetButtonImages(GetDlgItem(hdlg, IDC_BTN_EJECT), hmlilButton, IDB_EJECT2_NORMAL,
  251. IDB_EJECT2_PRESSED, IDB_EJECT2_HIGHLIGHTED, IDB_EJECT2_DISABLED);
  252. DataCmdBar_UpdateControls(hdlg, FALSE);
  253. return FALSE;
  254. }
  255. static void DataCmdBar_OnDestroy(HWND hdlg)
  256. {
  257. if (hmlilButton)
  258. {
  259. MLImageList_Destroy(plugin.hwndLibraryParent, hmlilButton);
  260. hmlilButton = NULL;
  261. }
  262. }
  263. static void DataCmdBar_OnWindowPosChanged(HWND hdlg, WINDOWPOS *pwp)
  264. {
  265. if (0 == (SWP_NOSIZE & pwp->flags) || 0 != (SWP_FRAMECHANGED & pwp->flags))
  266. {
  267. HWND hctrl;
  268. HDWP hdwp;
  269. RECT rc, rw;
  270. DWORD flags;
  271. if (!GetClientRect(hdlg, &rc)) return;
  272. InflateRect(&rc, -2, 0);
  273. LONG left = rc.left-2;
  274. LONG right = rc.right;
  275. hdwp = BeginDeferWindowPos(4);
  276. if (!hdwp) return;
  277. flags = SWP_NOACTIVATE | SWP_NOZORDER | ((SWP_NOREDRAW | SWP_NOCOPYBITS) & pwp->flags);
  278. if (NULL != (hctrl = GetDlgItem(hdlg, IDC_BTN_PLAYEX)) && GetWindowRect(hctrl, &rw))
  279. {
  280. hdwp = DeferWindowPos(hdwp, hctrl, NULL, left, rc.top, rw.right - rw.left, rc.bottom - rc.top, flags);
  281. left += ((rw.right - rw.left) + 8);
  282. }
  283. if (NULL != (hctrl = GetDlgItem(hdlg, IDC_BTN_COPY)) && GetWindowRect(hctrl, &rw))
  284. {
  285. hdwp = DeferWindowPos(hdwp, hctrl, NULL, left, rc.top, rw.right - rw.left, rc.bottom - rc.top, flags);
  286. left += ((rw.right - rw.left) + 8);
  287. }
  288. if (NULL != (hctrl = GetDlgItem(hdlg, IDC_BTN_EJECT)) && GetWindowRect(hctrl, &rw))
  289. {
  290. right -= (rw.right - rw.left);
  291. if (right < (left + 16)) right = left + 16;
  292. hdwp = DeferWindowPos(hdwp, hctrl, NULL, right, rc.top, rw.right - rw.left, rc.bottom - rc.top, flags);
  293. right -= 4;
  294. }
  295. if (NULL != (hctrl = GetDlgItem(hdlg, IDC_LBL_STATUS)) && GetWindowRect(hctrl, &rw))
  296. {
  297. hdwp = DeferWindowPos(hdwp, hctrl, NULL, left, rc.top, right - left, rc.bottom - rc.top, flags);
  298. }
  299. EndDeferWindowPos(hdwp);
  300. }
  301. if (0 == (SWP_NOREDRAW & pwp->flags)) InvalidateRect(GetDlgItem(hdlg, IDC_LBL_STATUS), NULL, TRUE);
  302. }
  303. static void DataCmdBar_OnPlayDropDown(HWND hdlg, HWND hctrl)
  304. {
  305. RECT r;
  306. if (!GetWindowRect(hctrl, &r)) return;
  307. HWND hFileView = (HWND)CommandBar_GetData(hdlg);
  308. if (NULL == hFileView) return;
  309. HMENU hMenu = FileView_GetMenu(hFileView, FVMENU_PLAY);
  310. if (!hMenu) return;
  311. MLSkinnedButton_SetDropDownState(hctrl, TRUE);
  312. HMLIMGLST hmlilDropDown = DataCmdBar_CreateDropDownImageList(hMenu);
  313. MLTrackSkinnedPopupMenuEx(plugin.hwndLibraryParent, hMenu,
  314. TPM_RIGHTBUTTON | TPM_LEFTBUTTON | TPM_BOTTOMALIGN | TPM_LEFTALIGN | TPM_NONOTIFY,
  315. r.left, r.top - 2, hFileView, NULL, hmlilDropDown, r.right - r.left,
  316. SMS_USESKINFONT, NULL, 0L);
  317. MLSkinnedButton_SetDropDownState(hctrl, FALSE);
  318. MLImageList_Destroy(plugin.hwndLibraryParent, hmlilDropDown);
  319. }
  320. static void DataCmdBar_OnPlayClick(HWND hdlg, HWND hButton)
  321. {
  322. EnableWindow(hButton, FALSE);
  323. HWND hFileView = (HWND)CommandBar_GetData(hdlg);
  324. if (NULL != hFileView)
  325. {
  326. HMENU hMenu = FileView_GetMenu(hFileView, FVMENU_PLAY);
  327. if (NULL != hMenu)
  328. {
  329. UINT uCmd = (FVS_ENQUEUE & FileView_GetStyle(hFileView)) ? FVA_ENQUEUE : FVA_PLAY;
  330. SendMessageW(hFileView, WM_COMMAND, MAKEWPARAM(FileView_GetActionCommand(hFileView, uCmd), 0), 0L);
  331. }
  332. }
  333. EnableWindow(hButton, TRUE);
  334. }
  335. static void DataCmdBar_OnCommand(HWND hdlg, INT eventId, INT ctrlId, HWND hwndCtrl)
  336. {
  337. switch (ctrlId)
  338. {
  339. case IDC_BTN_PLAYEX:
  340. switch(eventId)
  341. {
  342. case MLBN_DROPDOWN: DataCmdBar_OnPlayDropDown(hdlg, hwndCtrl); break;
  343. case BN_CLICKED: DataCmdBar_OnPlayClick(hdlg, hwndCtrl); break;
  344. }
  345. break;
  346. case IDC_BTN_EJECT:
  347. switch(eventId)
  348. {
  349. case BN_CLICKED: SendMessageW(GetParent(hdlg), WM_COMMAND, MAKEWPARAM(ID_EJECT_DISC, 0), 0L); break; // straight to container...
  350. }
  351. break;
  352. case IDC_BTN_COPY:
  353. switch(eventId)
  354. {
  355. case BN_CLICKED: SendMessageW(hdlg, WM_COMMAND, MAKEWPARAM(ID_COPY_SELECTION, 0), 0L); break;
  356. }
  357. break;
  358. }
  359. }
  360. static INT DataCmdBar_OnGetBestHeight(HWND hdlg)
  361. {
  362. INT h, height = 0;
  363. INT buttonList[] = { IDC_BTN_PLAYEX, };
  364. for(int i =0; i < sizeof(buttonList)/sizeof(buttonList[0]); i++)
  365. {
  366. HWND hctrl = GetDlgItem(hdlg, buttonList[i]);
  367. if (NULL != hctrl)
  368. {
  369. DWORD sz = MLSkinnedButton_GetIdealSize(hctrl, NULL);
  370. h = HIWORD(sz);
  371. if (height < h) height = h;
  372. }
  373. }
  374. return height;
  375. }
  376. INT_PTR WINAPI DataCmdBar_DialogProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  377. {
  378. switch (uMsg)
  379. {
  380. case WM_INITDIALOG: return DataCmdBar_OnInitDialog(hdlg, (HWND)wParam, lParam);
  381. case WM_DESTROY: DataCmdBar_OnDestroy(hdlg); break;
  382. case WM_WINDOWPOSCHANGED: DataCmdBar_OnWindowPosChanged(hdlg, (WINDOWPOS*)lParam); return TRUE;
  383. case WM_COMMAND: DataCmdBar_OnCommand(hdlg, HIWORD(wParam), LOWORD(wParam), (HWND)lParam); break;
  384. case CBM_GETBESTHEIGHT: SetWindowLongPtrW(hdlg, DWLP_MSGRESULT, DataCmdBar_OnGetBestHeight(hdlg)); return TRUE;
  385. case WM_DISPLAYCHANGE:
  386. PlayEx_Initialize(hdlg);
  387. break;
  388. case WM_SETFONT:
  389. DataCmdBar_UpdateControls(hdlg, LOWORD(lParam));
  390. return 0;
  391. case WM_SETTEXT:
  392. case WM_GETTEXT:
  393. case WM_GETTEXTLENGTH:
  394. SetWindowLongPtrW(hdlg, DWLP_MSGRESULT, (LONGX86)(LONG_PTR)SendDlgItemMessageW(hdlg, IDC_LBL_STATUS, uMsg, wParam, lParam));
  395. return TRUE;
  396. }
  397. return 0;
  398. }