#include #include #include #include #include "resource.h" #include "defs.h" extern HFONT g_GUIFontBold; HWND Elv_hWnd; int Elv_iSelectedItem = -1; WNDPROC Elv_PrevProc; HWND ElvCreate(HWND hWnd) { HWND hElv; LVCOLUMN lvc; Elv_hWnd = hWnd; hElv = LvCreate(hWnd, (HMENU)IDC_EPISODELISTVIEW); lvc.mask = LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM; lvc.iSubItem = 0; lvc.pszText = TEXT("#"); lvc.cx = 42; ListView_InsertColumn(hElv, 0, &lvc); lvc.iSubItem = 1; lvc.pszText = TEXT("Title"); lvc.cx = 500; ListView_InsertColumn(hElv, 1, &lvc); ElvUpdate(); ElvSelectRecent(); return hElv; } LRESULT ElvHandleNotify(LPARAM lParam) { NMLISTVIEW *pNmLv; pNmLv = (NMLISTVIEW *)lParam; switch (pNmLv->hdr.code) { case LVN_ITEMCHANGED: if ((pNmLv->uChanged & LVIF_STATE) && (pNmLv->uNewState & LVIS_FOCUSED)) { Elv_iSelectedItem = pNmLv->iItem; ElvUpdateName(pNmLv->iItem, pNmLv->lParam); DlvShowEpisode(pNmLv->lParam); } break; case NM_CUSTOMDRAW: { NMLVCUSTOMDRAW *pLvCd; pLvCd = (NMLVCUSTOMDRAW *)lParam; switch (pLvCd->nmcd.dwDrawStage) { case CDDS_PREPAINT: return CDRF_NOTIFYITEMDRAW; break; case CDDS_ITEMPREPAINT: if (!Watched(pLvCd->nmcd.lItemlParam)) { SelectObject(pLvCd->nmcd.hdc, g_GUIFontBold); return CDRF_NEWFONT; } break; } break; } case NM_DBLCLK: { term_t t; t = T(1); PI(t+0, ElvItemEpisode(Elv_iSelectedItem)) break; P("local_episodes","open_episode",1,t); break; } case NM_RCLICK: { DWORD dwPos; NMITEMACTIVATE *pNmItem; extern HMENU g_hPopupMenu; dwPos = GetMessagePos(); TrackPopupMenu(g_hPopupMenu, TPM_RIGHTBUTTON, LOWORD(dwPos), HIWORD(dwPos), 0, Elv_hWnd, NULL); break; } } return 0; } int ElvItemEpisode(int iItem) { HWND hElv; LVITEM lvi; hElv = GetDlgItem(Elv_hWnd, IDC_EPISODELISTVIEW); lvi.mask = LVIF_PARAM; lvi.iItem = iItem; lvi.iSubItem = 0; return ListView_GetItem(hElv, &lvi) ? lvi.lParam : -1; } void ElvRedraw() { HWND hElv; hElv = GetDlgItem(Elv_hWnd, IDC_EPISODELISTVIEW); RedrawWindow(hElv, NULL, NULL, RDW_ERASE|RDW_FRAME|RDW_INVALIDATE|RDW_ALLCHILDREN); } /* Select most recent episode. */ void ElvSelectRecent() { fid_t f; HWND hElv; int iEpisode, iItem; LVFINDINFO lvfi; term_t t; F(f); t = T(1); P("track_episodes","most_recently_watched",1,t) goto e; GI(t, &iEpisode) goto e; hElv = GetDlgItem(Elv_hWnd, IDC_EPISODELISTVIEW); lvfi.flags = LVFI_PARAM; lvfi.lParam = iEpisode; iItem = ListView_FindItem(hElv, -1, &lvfi); if (iItem == -1) goto e; ListView_EnsureVisible(hElv, iItem, TRUE); ListView_SetItemState(hElv, iItem, LVIS_SELECTED, LVIS_SELECTED); Elv_iSelectedItem = iItem; ElvUpdateName(iItem, iEpisode); DlvShowEpisode(iEpisode); e: Fd(f); } /* Update episode list. */ void ElvUpdate() { fid_t f; HWND hElv; int iLast, iTop; LVITEM lviEpisode, lviName; qid_t q; term_t t; hElv = GetDlgItem(Elv_hWnd, IDC_EPISODELISTVIEW); SendMessage(hElv, WM_SETREDRAW, FALSE, 0); iTop = ListView_GetTopIndex(hElv); ListView_DeleteAllItems(hElv); lviEpisode.mask = LVIF_TEXT|LVIF_PARAM; lviName.mask = LVIF_TEXT; F(f); t = T(2); P("track_episodes","update_tracked_episodes",0,t); q = Q("local_episodes","episode_file",2,t); for (int i = 0; Qn(q); i++) { char *szName; fid_t f2; int cb, iEpisode, iItem, r; TCHAR *tszEpisode, *tszName; term_t t2; /* Format name string. */ GI(t,&iEpisode) goto e; F(f2); t2 = T(3); PI(t2,iEpisode) goto e; tszName = NULL; P("episode_data","lookup_episode_local",3,t2) goto skipname; GAC(t2+1,&szName) goto skipname; tszName = TSZFromSZ(szName, CP_UTF8); if (!tszName) goto e; /* Format episode string. */ skipname: cb = 100; tszEpisode = malloc(cb*sizeof(TCHAR)); if (!tszEpisode) goto e1; _stprintf_s(tszEpisode, cb, TEXT("%d"), iEpisode); /* Insert item. */ lviEpisode.iItem = i; lviEpisode.iSubItem = 0; lviEpisode.pszText = tszEpisode; lviEpisode.lParam = iEpisode; ListView_InsertItem(hElv, &lviEpisode); if (tszName) { lviName.iItem = i; lviName.iSubItem = 1; lviName.pszText = tszName; ListView_SetItem(hElv, &lviName); } free(tszEpisode); e1: if (tszName) free(tszName); e: Fd(f2); } /* Reset selection and scrolling position. */ iLast = ListView_GetItemCount(hElv)-1; ListView_EnsureVisible(hElv, iLast, TRUE); ListView_EnsureVisible(hElv, iTop, TRUE); if (Elv_iSelectedItem != -1) { ListView_SetItemState(hElv, Elv_iSelectedItem, LVIS_SELECTED, LVIS_SELECTED); } SendMessage(hElv, WM_SETREDRAW, TRUE, 0); ElvRedraw(); Qc(q); Fd(f); } /* Update episode name. */ void ElvUpdateName(int iItem, int iEpisode) { char *szName; fid_t f; HWND hElv; TCHAR *tszName; term_t t; F(f); t = T(3); PI(t,iEpisode) goto e; P("episode_data","lookup_episode",3,t) goto e; GAC(t+1,&szName) goto e; tszName = TSZFromSZ(szName, CP_UTF8); if (!tszName) goto e; hElv = GetDlgItem(Elv_hWnd, IDC_EPISODELISTVIEW); ListView_SetItemText(hElv, iItem, 1, tszName); e: Fd(f); return; }