view.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. #include <strsafe.h>
  2. #include "main.h"
  3. #include <shellapi.h>
  4. #include "../nu/DialogSkinner.h"
  5. #include "../nu/ListView.h"
  6. #include "../../General/gen_ml/ml_ipc.h"
  7. #include "../../General/gen_ml/menu.h"
  8. #include "../WAT/WAT.h"
  9. #ifdef _DEBUG
  10. constexpr auto FANZONE_BASE_URL = L"https://player-stg.winamp.com/fanzone/music?mtm_campaign=legendary_player";
  11. #else
  12. constexpr auto FANZONE_BASE_URL = L"https://player.winamp.com/fanzone/music?mtm_campaign=legendary_player";
  13. #endif // _DEBUG
  14. INT_PTR CALLBACK view_FANZONEDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam);
  15. static W_ListView m_fanzone_node;
  16. static HWND m_headerhwnd;
  17. extern C_Config *g_config;
  18. extern char *g_ext_list;
  19. static int customAllowed;
  20. static viewButtons view;
  21. C_Config *g_wa_config = 0;
  22. char *g_ext_list = 0;
  23. // used for the send-to menu bits
  24. static INT_PTR IPC_LIBRARY_SENDTOMENU;
  25. static librarySendToMenuStruct s;
  26. BOOL myMenu = FALSE;
  27. extern HMENU g_context_menus, g_context_menus2;
  28. extern HCURSOR hDragNDropCursor;
  29. static int FANZONE_contextMenu( INT_PTR param1, HWND hHost, POINTS pts )
  30. {
  31. return TRUE;
  32. }
  33. static int pluginHandleIpcMessage(int msg, int param)
  34. {
  35. return (int)SendMessage( plugin.hwndLibraryParent, WM_ML_IPC, param, msg );
  36. }
  37. INT_PTR fanzone_pluginMessageProc( int message_type, INT_PTR param1, INT_PTR param2, INT_PTR param3 )
  38. {
  39. if ( message_type == ML_MSG_NO_CONFIG )
  40. {
  41. return TRUE;
  42. }
  43. else if ( message_type == ML_MSG_TREE_ONCREATEVIEW && param1 == fanzone_treeItem )
  44. {
  45. return (INT_PTR)WASABI_API_CREATEDIALOGW( IDD_VIEW_FANZONE, (HWND)param2, view_FANZONEDialogProc );
  46. }
  47. else if ( message_type == ML_MSG_NAVIGATION_CONTEXTMENU )
  48. {
  49. return FANZONE_contextMenu( param1, (HWND)param2, MAKEPOINTS( param3 ) );
  50. }
  51. else if ( message_type == ML_MSG_ONSENDTOSELECT || message_type == ML_MSG_TREE_ONDROPTARGET )
  52. {
  53. // set with droptarget defaults =)
  54. UINT_PTR type = 0, data = 0;
  55. if ( message_type == ML_MSG_ONSENDTOSELECT )
  56. {
  57. if ( param3 != (INT_PTR)fanzone_pluginMessageProc ) return 0;
  58. type = (int)param1;
  59. data = (int)param2;
  60. }
  61. else
  62. {
  63. if ( param1 != fanzone_treeItem ) return 0;
  64. type = (int)param2;
  65. data = (int)param3;
  66. if ( !data )
  67. {
  68. return ( type == ML_TYPE_ITEMRECORDLISTW || type == ML_TYPE_ITEMRECORDLIST ||
  69. type == ML_TYPE_FILENAMES || type == ML_TYPE_STREAMNAMES ||
  70. type == ML_TYPE_FILENAMESW || type == ML_TYPE_STREAMNAMESW ||
  71. type == ML_TYPE_CDTRACKS ||
  72. type == ML_TYPE_PLAYLIST || type == ML_TYPE_PLAYLISTS ) ? 1 : -1;
  73. }
  74. }
  75. }
  76. else if ( message_type == WM_WA_IPC )
  77. {
  78. int l_toto = 0;
  79. }
  80. else if ( message_type == IPC_SETVOLUME )
  81. {
  82. int curvol = IPC_GETVOLUME( plugin.hwndWinampParent );
  83. int l_toto = 0;
  84. }
  85. else if ( message_type == WINAMP_VOLUMEDOWN )
  86. {
  87. int l_toto = 0;
  88. }
  89. else if ( message_type == WINAMP_VOLUMEUP )
  90. {
  91. int l_toto = 0;
  92. }
  93. return 0;
  94. }
  95. static HRGN g_rgnUpdate = NULL;
  96. static int offsetX = 0, offsetY = 0;
  97. typedef struct _LAYOUT
  98. {
  99. INT id;
  100. HWND hwnd;
  101. INT x;
  102. INT y;
  103. INT cx;
  104. INT cy;
  105. DWORD flags;
  106. HRGN rgn;
  107. }
  108. LAYOUT, PLAYOUT;
  109. #define SETLAYOUTPOS(_layout, _x, _y, _cx, _cy) { _layout->x=_x; _layout->y=_y;_layout->cx=_cx;_layout->cy=_cy;_layout->rgn=NULL; }
  110. #define SETLAYOUTFLAGS(_layout, _r) \
  111. { \
  112. BOOL fVis; \
  113. fVis = (WS_VISIBLE & (LONG)GetWindowLongPtr(_layout->hwnd, GWL_STYLE)); \
  114. if (_layout->x == _r.left && _layout->y == _r.top) _layout->flags |= SWP_NOMOVE; \
  115. if (_layout->cx == (_r.right - _r.left) && _layout->cy == (_r.bottom - _r.top)) _layout->flags |= SWP_NOSIZE; \
  116. if ((SWP_HIDEWINDOW & _layout->flags) && !fVis) _layout->flags &= ~SWP_HIDEWINDOW; \
  117. if ((SWP_SHOWWINDOW & _layout->flags) && fVis) _layout->flags &= ~SWP_SHOWWINDOW; \
  118. }
  119. #define LAYOUTNEEEDUPDATE(_layout) ((SWP_NOMOVE | SWP_NOSIZE) != ((SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW | SWP_SHOWWINDOW) & _layout->flags))
  120. #define GROUP_MIN 0x1
  121. #define GROUP_MAX 0x2
  122. #define GROUP_STATUSBAR 0x1
  123. #define GROUP_MAIN 0x2
  124. static void LayoutWindows(HWND hwnd, BOOL fRedraw, BOOL fUpdateAll = FALSE)
  125. {
  126. static INT controls[] =
  127. {
  128. GROUP_STATUSBAR, GROUP_MAIN, IDC_LIST_FANZONE
  129. };
  130. INT index;
  131. RECT rc, rg, ri;
  132. LAYOUT layout[ sizeof( controls ) / sizeof( controls[ 0 ] ) ], *pl;
  133. BOOL skipgroup;
  134. HRGN rgn = NULL;
  135. GetClientRect(hwnd, &rc);
  136. if ( rc.right == rc.left || rc.bottom == rc.top )
  137. return;
  138. if ( rc.right > WASABI_API_APP->getScaleX( 4 ) )
  139. rc.right -= WASABI_API_APP->getScaleX( 4 );
  140. SetRect(&rg, rc.left, rc.top, rc.right, rc.top);
  141. pl = layout;
  142. skipgroup = FALSE;
  143. InvalidateRect(hwnd, NULL, TRUE);
  144. for ( index = 0; index < sizeof( controls ) / sizeof( *controls ); index++ )
  145. {
  146. if ( controls[ index ] >= GROUP_MIN && controls[ index ] <= GROUP_MAX ) // group id
  147. {
  148. skipgroup = FALSE;
  149. switch ( controls[ index ] )
  150. {
  151. case GROUP_MAIN:
  152. SetRect( &rg, rc.left + WASABI_API_APP->getScaleX( 1 ), rc.top, rc.right, rc.bottom );
  153. break;
  154. }
  155. continue;
  156. }
  157. if (skipgroup)
  158. continue;
  159. pl->id = controls[ index ];
  160. pl->hwnd = GetDlgItem( hwnd, pl->id );
  161. if ( !pl->hwnd )
  162. continue;
  163. GetWindowRect( pl->hwnd, &ri );
  164. MapWindowPoints( HWND_DESKTOP, hwnd, (LPPOINT)&ri, 2 );
  165. pl->flags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOCOPYBITS;
  166. switch (pl->id)
  167. {
  168. case IDC_LIST_FANZONE:
  169. pl->flags |= (rg.top < rg.bottom) ? SWP_SHOWWINDOW : SWP_HIDEWINDOW;
  170. SETLAYOUTPOS(pl, rg.left, rg.top + WASABI_API_APP->getScaleY(1),
  171. rg.right - rg.left + WASABI_API_APP->getScaleY(1),
  172. (rg.bottom - rg.top) - WASABI_API_APP->getScaleY(2));
  173. break;
  174. }
  175. SETLAYOUTFLAGS( pl, ri );
  176. if ( LAYOUTNEEEDUPDATE( pl ) )
  177. {
  178. if ( SWP_NOSIZE == ( ( SWP_HIDEWINDOW | SWP_SHOWWINDOW | SWP_NOSIZE ) & pl->flags ) && ri.left == ( pl->x + offsetX ) && ri.top == ( pl->y + offsetY ) && IsWindowVisible( pl->hwnd ) )
  179. {
  180. SetRect( &ri, pl->x, pl->y, pl->cx + pl->x, pl->y + pl->cy );
  181. ValidateRect( hwnd, &ri );
  182. }
  183. pl++;
  184. }
  185. else if ((fRedraw || (!offsetX && !offsetY)) && IsWindowVisible(pl->hwnd))
  186. {
  187. ValidateRect(hwnd, &ri);
  188. if ( GetUpdateRect( pl->hwnd, NULL, FALSE ) )
  189. {
  190. if ( !rgn )
  191. rgn = CreateRectRgn( 0, 0, 0, 0 );
  192. GetUpdateRgn( pl->hwnd, rgn, FALSE );
  193. OffsetRgn( rgn, pl->x, pl->y );
  194. InvalidateRgn( hwnd, rgn, FALSE );
  195. }
  196. }
  197. }
  198. if (pl != layout)
  199. {
  200. LAYOUT *pc;
  201. HDWP hdwp = BeginDeferWindowPos( (INT)( pl - layout ) );
  202. for ( pc = layout; pc < pl && hdwp; pc++ )
  203. {
  204. hdwp = DeferWindowPos( hdwp, pc->hwnd, NULL, pc->x, pc->y, pc->cx, pc->cy, pc->flags );
  205. }
  206. if ( hdwp )
  207. EndDeferWindowPos( hdwp );
  208. if ( !rgn )
  209. rgn = CreateRectRgn( 0, 0, 0, 0 );
  210. if ( fRedraw )
  211. {
  212. GetUpdateRgn( hwnd, rgn, FALSE );
  213. for ( pc = layout; pc < pl && hdwp; pc++ )
  214. {
  215. if ( pc->rgn )
  216. {
  217. OffsetRgn( pc->rgn, pc->x, pc->y );
  218. CombineRgn( rgn, rgn, pc->rgn, RGN_OR );
  219. }
  220. }
  221. RedrawWindow( hwnd, NULL, rgn, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASENOW | RDW_ALLCHILDREN );
  222. }
  223. if ( g_rgnUpdate )
  224. {
  225. GetUpdateRgn( hwnd, g_rgnUpdate, FALSE );
  226. for ( pc = layout; pc < pl && hdwp; pc++ )
  227. {
  228. if ( pc->rgn )
  229. {
  230. OffsetRgn( pc->rgn, pc->x, pc->y );
  231. CombineRgn( g_rgnUpdate, g_rgnUpdate, pc->rgn, RGN_OR );
  232. }
  233. }
  234. }
  235. for ( pc = layout; pc < pl && hdwp; pc++ )
  236. if ( pc->rgn )
  237. DeleteObject( pc->rgn );
  238. }
  239. if ( rgn )
  240. DeleteObject( rgn );
  241. ValidateRgn( hwnd, NULL );
  242. }
  243. static BOOL FANZONE_OnDisplayChange()
  244. {
  245. ListView_SetTextColor( m_fanzone_node.getwnd(), dialogSkinner.Color( WADLG_ITEMFG ) );
  246. ListView_SetBkColor( m_fanzone_node.getwnd(), dialogSkinner.Color( WADLG_ITEMBG ) );
  247. ListView_SetTextBkColor( m_fanzone_node.getwnd(), dialogSkinner.Color( WADLG_ITEMBG ) );
  248. m_fanzone_node.SetFont( dialogSkinner.GetFont() );
  249. LayoutWindows( m_hwnd, TRUE );
  250. // Display the modal windows
  251. ShowWindow( m_fanzone_node.getwnd(), SW_SHOW );
  252. UpdateWindow( m_fanzone_node.getwnd() );
  253. return 0;
  254. }
  255. enum
  256. {
  257. BPM_ECHO_WM_COMMAND = 0x1, // send WM_COMMAND and return value
  258. BPM_WM_COMMAND = 0x2, // just send WM_COMMAND
  259. };
  260. static BOOL FANZONE_OnCommand( HWND hwnd, int id, HWND hwndCtl, UINT codeNotify )
  261. {
  262. return FALSE;
  263. }
  264. static BOOL FANZONE_OnDestroy(HWND hwnd)
  265. {
  266. m_hwnd = 0;
  267. return FALSE;
  268. }
  269. static BOOL FANZONE_OnNotify(HWND hwnd, NMHDR *notification)
  270. {
  271. if (notification->idFrom == IDC_LIST_FANZONE)
  272. {
  273. if (notification->code == LVN_BEGINDRAG)
  274. {
  275. SetCapture(hwnd);
  276. }
  277. }
  278. return FALSE;
  279. }
  280. static BOOL FANZONE_OnInitDialog(HWND hwndDlg, HWND hwndFocus, LPARAM lParam)
  281. {
  282. m_hwnd = hwndDlg;
  283. m_fanzone_node.setwnd(GetDlgItem(hwndDlg, IDC_LIST_FANZONE));
  284. if (!view.play)
  285. {
  286. SENDMLIPC(plugin.hwndLibraryParent, ML_IPC_GET_VIEW_BUTTON_TEXT, (WPARAM)&view);
  287. }
  288. FANZONE_OnDisplayChange();
  289. m_headerhwnd = ListView_GetHeader( m_fanzone_node.getwnd() );
  290. // v5.66+ - re-use the old predixis parts so the button can be used functionally via ml_enqplay
  291. // pass the hwnd, button id and plug-in id so the ml plug-in can check things as needed
  292. customAllowed = FALSE;
  293. MLSKINWINDOW l_ml_skin_window = {0};
  294. l_ml_skin_window.skinType = SKINNEDWND_TYPE_DIALOG;
  295. l_ml_skin_window.style = SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWS_USESKINFONT;
  296. l_ml_skin_window.hwndToSkin = m_hwnd;
  297. MLSkinWindow( plugin.hwndLibraryParent, &l_ml_skin_window );
  298. //l_ml_skin_window.skinType = SKINNEDWND_TYPE_STATIC;
  299. //l_ml_skin_window.style = SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWS_USESKINFONT;
  300. //l_ml_skin_window.hwndToSkin = m_hwnd;
  301. //MLSkinWindow( mediaLibrary.library, &l_ml_skin_window );
  302. ShellExecuteW(NULL, L"open", FANZONE_BASE_URL, NULL, NULL, SW_SHOWNORMAL);
  303. delete g_wa_config;
  304. SetTimer( m_hwnd, 100, 15, NULL );
  305. return TRUE;
  306. }
  307. INT_PTR CALLBACK view_FANZONEDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
  308. {
  309. INT_PTR a = dialogSkinner.Handle(hwndDlg, uMsg, wParam, lParam);
  310. if (a) return a;
  311. switch(uMsg)
  312. {
  313. HANDLE_MSG(hwndDlg, WM_INITDIALOG, FANZONE_OnInitDialog);
  314. HANDLE_MSG(hwndDlg, WM_COMMAND, FANZONE_OnCommand);
  315. HANDLE_MSG(hwndDlg, WM_DESTROY, FANZONE_OnDestroy);
  316. case WM_WINDOWPOSCHANGED:
  317. if ((SWP_NOSIZE | SWP_NOMOVE) != ((SWP_NOSIZE | SWP_NOMOVE) & ((WINDOWPOS*)lParam)->flags) ||
  318. (SWP_FRAMECHANGED & ((WINDOWPOS*)lParam)->flags))
  319. {
  320. LayoutWindows(hwndDlg, !(SWP_NOREDRAW & ((WINDOWPOS*)lParam)->flags));
  321. }
  322. return 0;
  323. case WM_USER + 0x200:
  324. SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, 1); // yes, we support no - redraw resize
  325. return TRUE;
  326. case WM_USER + 0x201:
  327. offsetX = (short)LOWORD(wParam);
  328. offsetY = (short)HIWORD(wParam);
  329. g_rgnUpdate = (HRGN)lParam;
  330. return TRUE;
  331. case WM_PAINT:
  332. {
  333. int tab[] = { IDC_LIST_FANZONE | DCW_SUNKENBORDER };
  334. dialogSkinner.Draw(hwndDlg, tab, sizeof(tab) / sizeof(tab[0]));
  335. }
  336. return 0;
  337. case WM_INITMENUPOPUP:
  338. if (wParam && (HMENU)wParam == s.build_hMenu && s.mode==1)
  339. {
  340. myMenu = TRUE;
  341. if(SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_LIBRARY_SENDTOMENU)==0xffffffff)
  342. s.mode=2;
  343. myMenu = FALSE;
  344. }
  345. return 0;
  346. case WM_DISPLAYCHANGE:
  347. return FANZONE_OnDisplayChange();
  348. case WM_NOTIFY:
  349. return FANZONE_OnNotify(hwndDlg, (LPNMHDR)lParam);
  350. }
  351. return FALSE;
  352. }