wa2pldirobj.cpp 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. #include <precomp.h>
  2. #include "main.h"
  3. #include "wa2pldirobj.h"
  4. #include "wa2frontend.h"
  5. #include <bfc/util/timefmt.h>
  6. #include "wa2pledit.h"
  7. /*
  8. TODO:
  9. register for playlists callbacks so we can keep up to date
  10. drag&drop re-ordering
  11. in-place renaming
  12. widget for editing playlists
  13. */
  14. const wchar_t plDirXuiObjectStr[] = L"PlaylistDirectory"; // This is the xml tag
  15. char plDirXuiSvcName[] = "Playlist Directory XUI object"; // this is the name of the xuiservice
  16. static PlDirScriptObjectController _pldirController;
  17. ScriptObjectController *pldirController = &_pldirController;
  18. BEGIN_SERVICES(wa2PlDirObj_Svcs);
  19. DECLARE_SERVICETSINGLE(svc_scriptObject, PlDirScriptObjectSvc);
  20. DECLARE_SERVICE(XuiObjectCreator<PlDirXuiSvc>);
  21. END_SERVICES(wa2PlDirObj_Svcs, _wa2PlDirObj_Svcs);
  22. #define CB_POPULATE 0x6273
  23. #ifdef _X86_
  24. extern "C"
  25. {
  26. int _link_wa2PlDirObj_Svcs;
  27. }
  28. #else
  29. extern "C"
  30. {
  31. int __link_wa2PlDirObj_Svcs;
  32. }
  33. #endif
  34. // -----------------------------------------------------------------------------------------------------
  35. // Service
  36. ScriptObjectController *PlDirScriptObjectSvc::getController(int n)
  37. {
  38. switch (n)
  39. {
  40. case 0:
  41. return pldirController;
  42. }
  43. return NULL;
  44. }
  45. // -----------------------------------------------------------------------------------------------------
  46. // PlDirObject
  47. PlDirObject::PlDirObject()
  48. {
  49. getScriptObject()->vcpu_setInterface(PLDIR_SCRIPTOBJECT_GUID, (void *)static_cast<PlDirObject *>(this));
  50. getScriptObject()->vcpu_setClassName(L"PlDir");
  51. getScriptObject()->vcpu_setController(pldirController);
  52. _pldirController.mylist.addItem(this);
  53. }
  54. PlDirObject::~PlDirObject()
  55. {
  56. int numItems = getItemCount();
  57. for (int i=0;i<numItems;i++)
  58. {
  59. GUID *playlist_guid = (GUID *)getItemData(i);
  60. if (playlist_guid)
  61. delete playlist_guid;
  62. }
  63. if (WASABI_API_SYSCB) WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<PlaylistCallbackI *>(this));
  64. _pldirController.mylist.removeItem(this);
  65. }
  66. int PlDirObject::playlistcb_added(size_t index)
  67. {
  68. postDeferredCallback(CB_POPULATE);
  69. return 1;
  70. }
  71. int PlDirObject::playlistcb_saved(size_t index)
  72. {
  73. postDeferredCallback(CB_POPULATE);
  74. return 1;
  75. }
  76. int PlDirObject::onDeferredCallback(intptr_t p1, intptr_t p2)
  77. {
  78. if (p1 == CB_POPULATE)
  79. {
  80. Populate();
  81. return 1;
  82. }
  83. return ListWnd::onDeferredCallback(p1, p2);
  84. }
  85. void PlDirObject::Populate()
  86. {
  87. int numItems = getItemCount();
  88. for (int i=0;i<numItems;i++)
  89. {
  90. GUID *playlist_guid = (GUID *)getItemData(i);
  91. if (playlist_guid)
  92. delete playlist_guid;
  93. }
  94. deleteAllItems();
  95. if (AGAVE_API_PLAYLISTS)
  96. {
  97. AGAVE_API_PLAYLISTS->Lock();
  98. size_t count = AGAVE_API_PLAYLISTS->GetCount();
  99. for (size_t i=0;i!=count;i++)
  100. {
  101. const wchar_t *playlistName = AGAVE_API_PLAYLISTS->GetName(i);
  102. GUID *playlist_guid = new GUID(AGAVE_API_PLAYLISTS->GetGUID(i));
  103. addItem(playlistName, (LPARAM)playlist_guid); // TODO: malloc pointer to GUID and store
  104. wchar_t temp[256] = {0};
  105. size_t numItems=0;
  106. AGAVE_API_PLAYLISTS->GetInfo(i, api_playlists_itemCount, &numItems, sizeof(numItems));
  107. WCSNPRINTF(temp, 256, L"%u", numItems);
  108. this->setSubItem(i, 1, temp);
  109. AGAVE_API_PLAYLISTS->GetInfo(i, api_playlists_totalTime, &numItems, sizeof(numItems)); //numitems holds now time
  110. wchar_t buf[1024] = {0};
  111. TimeFmt::printHourMinSec(numItems, buf, 1024, 1);
  112. this->setSubItem(i, 2, buf);
  113. }
  114. AGAVE_API_PLAYLISTS->Unlock();
  115. }
  116. }
  117. int PlDirObject::onInit()
  118. {
  119. /*colresize = 1;
  120. resizing_col = true;
  121. colresizeo = 1;*/
  122. ListWnd::onInit();
  123. setName(L"Playlists");
  124. //setItemIcon(
  125. //setShowColumnsHeaders(FALSE);
  126. ListColumn *nameCol = new ListColumn(L"Playlist Title", 1);
  127. //nameCol->setWidth(100);
  128. insertColumn(nameCol);
  129. /*ListColumn *countCol= new ListColumn(L"Items", 0);
  130. countCol->setWidth(40);
  131. countCol->setAlignment(COL_RIGHTALIGN);
  132. insertColumn(countCol,1,COL_RIGHTALIGN);
  133. ListColumn *lenCol= new ListColumn(L"Time", 0);
  134. lenCol->setWidth(50);
  135. lenCol->setAlignment(COL_CENTERALIGN);
  136. insertColumn(lenCol, 1, COL_CENTERALIGN);
  137. insertColumn(lenCol);*/
  138. addColumn(L"Items", 40, 0, COL_RIGHTALIGN);
  139. addColumn(L"Time", 55, 0, COL_RIGHTALIGN);
  140. //addColumn(L"Time", 100);
  141. Populate();
  142. WASABI_API_SYSCB->syscb_registerCallback(static_cast<PlaylistCallbackI *>(this));
  143. return 1;
  144. }
  145. /*
  146. int PlDirObject::onResize()
  147. {
  148. ListWnd::onResize();
  149. RECT r;
  150. getClientRect(&r);
  151. ListColumn *lc = getColumn(0);
  152. lc->setWidth(r.right - r.left);
  153. return 1;
  154. }*/
  155. void PlDirObject::onDoubleClick(int itemnum)
  156. {
  157. ListWnd::onDoubleClick(itemnum);
  158. // find a playlisteditor object near us
  159. Wa2PlaylistEditor *editor = static_cast<Wa2PlaylistEditor *>(findWindowByInterface(Wa2PlaylistEditor::getInterfaceGuid()));
  160. if (editor != NULL)
  161. {
  162. Wa2Playlist *playlist = getPlaylist(itemnum);
  163. editor->setPlaylist(playlist);
  164. }
  165. GUID *playlist_guid = (GUID *)this->getItemData(itemnum);
  166. if (playlist_guid)
  167. {
  168. size_t index;
  169. AGAVE_API_PLAYLISTS->Lock();
  170. if (AGAVE_API_PLAYLISTS->GetPosition(*playlist_guid, &index) == API_PLAYLISTS_SUCCESS)
  171. {
  172. // TODO: benski> try to retrieve setting from ml_playlists for play vs enqueue on double click
  173. const wchar_t *playlist_filename = AGAVE_API_PLAYLISTS->GetFilename(index);
  174. wa2.playFile(playlist_filename);
  175. }
  176. AGAVE_API_PLAYLISTS->Unlock();
  177. }
  178. }
  179. Wa2Playlist *PlDirObject::getPlaylist(int itemnum)
  180. {
  181. return (Wa2Playlist *) - 1;
  182. }
  183. // -----------------------------------------------------------------------------------------------------
  184. // PlDirScriptObjectController
  185. function_descriptor_struct PlDirScriptObjectController::exportedFunction[] = {
  186. {L"showCurrentlyPlayingEntry", 0, (void*)PlDirScriptObjectController::pldir_showCurrentlyPlayingEntry},
  187. {L"getNumItems", 0, (void*)PlDirScriptObjectController::pldir_getNumItems},
  188. {L"renameItem", 2, (void*)PlDirScriptObjectController::pldir_renameItem},
  189. {L"getItemName", 1, (void*)PlDirScriptObjectController::pldir_getItemName},
  190. {L"playItem", 1, (void*)PlDirScriptObjectController::pldir_playItem},
  191. {L"enqueueItem", 1, (void*)PlDirScriptObjectController::pldir_enqueueItem},
  192. {L"refresh", 0, (void*)PlDirScriptObjectController::pldir_refresh},
  193. };
  194. int PlDirScriptObjectController::getNumFunctions()
  195. {
  196. return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
  197. }
  198. ScriptObject *PlDirScriptObjectController::instantiate()
  199. {
  200. PlDirObject *c = new PlDirObject;
  201. if (!c) return NULL;
  202. return c->getScriptObject();
  203. }
  204. void PlDirScriptObjectController::destroy(ScriptObject *o)
  205. {
  206. PlDirObject *obj = static_cast<PlDirObject *>(o->vcpu_getInterface(PLDIR_SCRIPTOBJECT_GUID));
  207. ASSERT(obj != NULL);
  208. delete obj;
  209. }
  210. PlDirScriptObjectController::~PlDirScriptObjectController()
  211. {
  212. // Destroy our list, otherwise we get a big bang on wasabi shutdown
  213. if (_pldirController.mylist.getNumItems() > 0)
  214. _pldirController.mylist.deleteAll();
  215. }
  216. void *PlDirScriptObjectController::encapsulate(ScriptObject *o)
  217. {
  218. return NULL; // nobody can inherits from me yet (see rootobj or guiobj in studio if you want to allow that)
  219. }
  220. void PlDirScriptObjectController::deencapsulate(void *)
  221. {}
  222. // Script calls
  223. scriptVar PlDirScriptObjectController::pldir_showCurrentlyPlayingEntry(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
  224. {
  225. SCRIPT_FUNCTION_INIT
  226. HWND hPeWindow = wa2.getWnd(IPC_GETWND_PE);
  227. SendMessageW(hPeWindow, WM_USER, 666, wa2.PE_getCurrentIndex());
  228. RETURN_SCRIPT_VOID;
  229. }
  230. scriptVar PlDirScriptObjectController::pldir_getNumItems(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
  231. {
  232. SCRIPT_FUNCTION_INIT
  233. AGAVE_API_PLAYLISTS->Lock();
  234. size_t n = AGAVE_API_PLAYLISTS->GetCount();
  235. AGAVE_API_PLAYLISTS->Unlock();
  236. return MAKE_SCRIPT_INT(n);
  237. }
  238. scriptVar PlDirScriptObjectController::pldir_refresh(SCRIPT_FUNCTION_PARAMS, ScriptObject *o)
  239. {
  240. SCRIPT_FUNCTION_INIT
  241. for (int i = 0; i < _pldirController.mylist.getNumItems(); i++)
  242. {
  243. PlDirObject *p = _pldirController.mylist.enumItem(i);
  244. if (p) p->Populate();
  245. }
  246. // TODO: add refresh for ml pl view!
  247. //HWND hMlWindow = wa2.getMediaLibrary();
  248. //SendMessageW(hMlWindow, ???);
  249. //AGAVE_API_PLAYLISTS->MoveBefore(2,1);
  250. RETURN_SCRIPT_VOID;
  251. }
  252. scriptVar PlDirScriptObjectController::pldir_renameItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item, scriptVar name)
  253. {
  254. SCRIPT_FUNCTION_INIT
  255. AGAVE_API_PLAYLISTS->Lock();
  256. AGAVE_API_PLAYLISTS->RenamePlaylist(GET_SCRIPT_INT(item), GET_SCRIPT_STRING(name));
  257. AGAVE_API_PLAYLISTS->Unlock();
  258. for (int i = 0; i < _pldirController.mylist.getNumItems(); i++)
  259. {
  260. PlDirObject* p = _pldirController.mylist.enumItem(i);
  261. if (p) p->Populate();
  262. }
  263. //AGAVE_API_PLAYLISTS->MoveBefore(2,1);
  264. RETURN_SCRIPT_VOID;
  265. }
  266. scriptVar PlDirScriptObjectController::pldir_getItemName(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar item)
  267. {
  268. SCRIPT_FUNCTION_INIT
  269. AGAVE_API_PLAYLISTS->Lock();
  270. const wchar_t *k = AGAVE_API_PLAYLISTS->GetName(GET_SCRIPT_INT(item));
  271. AGAVE_API_PLAYLISTS->Unlock();
  272. return MAKE_SCRIPT_STRING(k);
  273. }
  274. scriptVar PlDirScriptObjectController::pldir_playItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _itemnum)
  275. {
  276. SCRIPT_FUNCTION_INIT
  277. int itemnum = GET_SCRIPT_INT(_itemnum);
  278. GUID playlist_guid = AGAVE_API_PLAYLISTS->GetGUID(itemnum);
  279. size_t index;
  280. AGAVE_API_PLAYLISTS->Lock();
  281. if (AGAVE_API_PLAYLISTS->GetPosition(playlist_guid, &index) == API_PLAYLISTS_SUCCESS)
  282. {
  283. // TODO: benski> try to retrieve setting from ml_playlists for play vs enqueue on double click
  284. const wchar_t *playlist_filename = AGAVE_API_PLAYLISTS->GetFilename(index);
  285. wa2.playFile(playlist_filename);
  286. }
  287. AGAVE_API_PLAYLISTS->Unlock();
  288. RETURN_SCRIPT_VOID
  289. }
  290. scriptVar PlDirScriptObjectController::pldir_enqueueItem(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar _itemnum)
  291. {
  292. SCRIPT_FUNCTION_INIT
  293. int itemnum = GET_SCRIPT_INT(_itemnum);
  294. GUID playlist_guid = AGAVE_API_PLAYLISTS->GetGUID(itemnum);
  295. size_t index;
  296. AGAVE_API_PLAYLISTS->Lock();
  297. if (AGAVE_API_PLAYLISTS->GetPosition(playlist_guid, &index) == API_PLAYLISTS_SUCCESS)
  298. {
  299. // TODO: benski> try to retrieve setting from ml_playlists for play vs enqueue on double click
  300. const wchar_t *playlist_filename = AGAVE_API_PLAYLISTS->GetFilename(index);
  301. wa2.enqueueFile(playlist_filename);
  302. }
  303. AGAVE_API_PLAYLISTS->Unlock();
  304. RETURN_SCRIPT_VOID
  305. }