From 8122c83bb3be30325f49d50dbafcd2f14c9b0d2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Mon, 11 Jul 2022 00:34:44 +0200 Subject: Improve ElvSort. --- c/datalistview.cpp | 16 ++++----- c/defs.h | 7 +++- c/episodelistview.cpp | 93 ++++++++++++++++++++++++++------------------------- c/listview.cpp | 5 ++- c/main.cpp | 53 ++++++++++++----------------- 5 files changed, 83 insertions(+), 91 deletions(-) (limited to 'c') diff --git a/c/datalistview.cpp b/c/datalistview.cpp index 3269dab..05d46a4 100644 --- a/c/datalistview.cpp +++ b/c/datalistview.cpp @@ -31,23 +31,18 @@ DataListView::Create() void DataListView::ShowEpisode(int iEpisode) { - int i, iItem; - LVFINDINFO lvfi; - LVITEM lviKey, lviValue; - term_t t; - qid_t q; - ListView_DeleteAllItems(m_hWnd); + LVITEM lviKey, lviValue; lviKey.mask = LVIF_TEXT; lviValue.mask = LVIF_TEXT; - t = PL_new_term_refs(3); + term_t t = PL_new_term_refs(3); if (!Plp(t,"I",iEpisode)) return; - q = PL_open_query(NULL, PL_Q_NORMAL, + qid_t q = PL_open_query(NULL, PL_Q_NORMAL, PL_predicate("episode_datum", 3, "episode_data"), t); - for (i = 0; PL_next_solution(q); i++) { + for (int i = 0; PL_next_solution(q); i++) { char *szKey; char *szValue; TCHAR *tszKey, *tszValue; @@ -77,9 +72,10 @@ DataListView::ShowEpisode(int iEpisode) PL_cut_query(q); UpdateLayout(); + LVFINDINFO lvfi; lvfi.flags = LVFI_PARAM; lvfi.lParam = iEpisode; - iItem = ListView_FindItem(g_elv.HWnd(), -1, &lvfi); + int iItem = ListView_FindItem(g_elv.HWnd(), -1, &lvfi); if (iItem != -1) ListView_EnsureVisible(g_elv.HWnd(), iItem, TRUE); } diff --git a/c/defs.h b/c/defs.h index f36b8ea..2fa2f06 100644 --- a/c/defs.h +++ b/c/defs.h @@ -19,17 +19,22 @@ protected: public: void Create(HMENU, DWORD); int Height(int); - HWND HWnd(void); + HWND HWnd(void) const; virtual void UpdateTheme(BOOL); virtual LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); }; /* episodelistview.cpp */ class EpisodeListView: public ListView { +private: + int m_iSort; + LVITEM m_lviFocus; public: void Create(void); void DoSort(void); + void EnsureFocusVisible(void); LRESULT HandleNotify(LPARAM); + int ISort(void) const; void Redraw(void); void SaveFocus(void); void SetTop(int); diff --git a/c/episodelistview.cpp b/c/episodelistview.cpp index 7c79043..88fb7ac 100644 --- a/c/episodelistview.cpp +++ b/c/episodelistview.cpp @@ -7,11 +7,6 @@ #include "defs.h" extern DataListView g_dlv; - -HWND HSortLv; - -int ISort; -LVITEM LviElvFocus; /* Focused episode. */ static int CALLBACK ElvSort(LPARAM, LPARAM, LPARAM); void @@ -37,47 +32,51 @@ EpisodeListView::Create() lvc.cx = Dpi(30); ListView_InsertColumn(m_hWnd, ELVSIRATING, &lvc); - if (!Pl("cfg","get_sort","i",&ISort)) - ISort = 1; + if (!Pl("cfg","get_sort","i",&m_iSort)) + m_iSort = 1; } void EpisodeListView::DoSort() { - HSortLv = m_hWnd; - ListView_SortItemsEx(m_hWnd, ElvSort, ISort); + ListView_SortItemsEx(m_hWnd, ElvSort, (LPARAM)this); +} + +void +EpisodeListView::EnsureFocusVisible() +{ + int iEpFocus = ListView_GetNextItem(m_hWnd, -1, LVNI_FOCUSED); + if (iEpFocus == -1) return; + ListView_EnsureVisible(m_hWnd, iEpFocus, TRUE); } LRESULT EpisodeListView::HandleNotify(LPARAM lParam) { - LPNMLISTVIEW lpNmLv; - lpNmLv = (LPNMLISTVIEW)lParam; + LPNMLISTVIEW lpNmLv = (LPNMLISTVIEW)lParam; switch (lpNmLv->hdr.code) { case LVN_ITEMCHANGED: /* Select/focus episode. */ if ((lpNmLv->uChanged & LVIF_STATE) && (lpNmLv->uNewState & LVIS_FOCUSED)) { - LviElvFocus.iItem = lpNmLv->iItem; - LviElvFocus.lParam = lpNmLv->lParam; - UpdateItem(&LviElvFocus); + m_lviFocus.iItem = lpNmLv->iItem; + m_lviFocus.lParam = lpNmLv->lParam; + UpdateItem(&m_lviFocus); g_dlv.ShowEpisode(lpNmLv->lParam); } break; case LVN_COLUMNCLICK: /* Sort by column. */ { - int iColumn; - iColumn = lpNmLv->iSubItem+1; - ISort = abs(ISort) == iColumn? -ISort: iColumn; - Pl("cfg","set_sort","I",ISort); + int iColumn = lpNmLv->iSubItem+1; + m_iSort = abs(m_iSort) == iColumn? -m_iSort: iColumn; + Pl("cfg","set_sort","I",m_iSort); DoSort(); ShowFocus(); break; } case LVN_KEYDOWN: /* Navigate episodes by keyboard. */ { - LPNMLVKEYDOWN lpNmLvKd; - lpNmLvKd = (LPNMLVKEYDOWN)lParam; + LPNMLVKEYDOWN lpNmLvKd = (LPNMLVKEYDOWN)lParam; switch (lpNmLvKd->wVKey) { case VK_LEFT: SelectUnwatched(-1); @@ -90,8 +89,7 @@ EpisodeListView::HandleNotify(LPARAM lParam) } case NM_CUSTOMDRAW: /* Make unwatched episodes bold. */ { - LPNMLVCUSTOMDRAW lpLvCd; - lpLvCd = (LPNMLVCUSTOMDRAW)lParam; + LPNMLVCUSTOMDRAW lpLvCd = (LPNMLVCUSTOMDRAW)lParam; switch (lpLvCd->nmcd.dwDrawStage) { case CDDS_PREPAINT: return CDRF_NOTIFYITEMDRAW; @@ -111,9 +109,9 @@ EpisodeListView::HandleNotify(LPARAM lParam) case NM_DBLCLK: /* Open clicked episode. */ { if (!Pl("local_episodes","open_episode_locally","I", - LviElvFocus.lParam)) + m_lviFocus.lParam)) Pl("local_episodes","open_episode_online","I", - LviElvFocus.lParam); + m_lviFocus.lParam); break; } case NM_RETURN: /* Open all selected episodes. */ @@ -133,10 +131,9 @@ EpisodeListView::HandleNotify(LPARAM lParam) } case NM_RCLICK: { - DWORD dwPos; extern HWND g_hWnd; extern HMENU g_hPopupMenu; - dwPos = GetMessagePos(); + DWORD dwPos = GetMessagePos(); TrackPopupMenu(g_hPopupMenu, TPM_RIGHTBUTTON, LOWORD(dwPos), HIWORD(dwPos), 0, g_hWnd, NULL); @@ -147,6 +144,12 @@ EpisodeListView::HandleNotify(LPARAM lParam) return 0; } +int +EpisodeListView::ISort() const +{ + return m_iSort; +} + void EpisodeListView::Redraw() { @@ -167,8 +170,7 @@ EpisodeListView::SaveFocus() void EpisodeListView::SetTop(int iItem) { - int iLast; - iLast = ListView_GetItemCount(m_hWnd)-1; + int iLast = ListView_GetItemCount(m_hWnd)-1; ListView_EnsureVisible(m_hWnd, iLast, TRUE); ListView_EnsureVisible(m_hWnd, iItem, TRUE); } @@ -202,9 +204,9 @@ s: ListView_SetItemState(m_hWnd, -1, LVIF_STATE, LVIS_SELECTED); SetTop(iItem > 5? iItem-5: 0); ListView_SetItemState(m_hWnd, iItem, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED); - LviElvFocus.iItem = iItem; - LviElvFocus.lParam = iEpisode; - UpdateItem(&LviElvFocus); + m_lviFocus.iItem = iItem; + m_lviFocus.lParam = iEpisode; + UpdateItem(&m_lviFocus); g_dlv.ShowEpisode(iEpisode); } @@ -212,11 +214,8 @@ s: ListView_SetItemState(m_hWnd, -1, LVIF_STATE, LVIS_SELECTED); void EpisodeListView::SelectUnwatched(int iDir) { - int i, iEpNew, iItemNew; - LVFINDINFO lvfi; - LVITEM lviFocus; - /* Get focused episode. */ + LVITEM lviFocus; lviFocus.mask = LVIF_PARAM; if ((lviFocus.iItem = ListView_GetNextItem(m_hWnd, -1, LVNI_FOCUSED)) != -1 && ListView_GetItem(m_hWnd, &lviFocus)) @@ -224,6 +223,8 @@ EpisodeListView::SelectUnwatched(int iDir) else return; + LVFINDINFO lvfi; + int i, iEpNew, iItemNew; i = 0; lvfi.flags = LVFI_PARAM; lvfi.lParam = lviFocus.lParam; @@ -250,8 +251,7 @@ EpisodeListView::SelectUnwatched(int iDir) void EpisodeListView::ShowFocus() { - int iEpFocus; - iEpFocus = ListView_GetNextItem(m_hWnd, -1, LVNI_FOCUSED); + int iEpFocus = ListView_GetNextItem(m_hWnd, -1, LVNI_FOCUSED); if (iEpFocus == -1) return; ListView_EnsureVisible(m_hWnd, iEpFocus, TRUE); } @@ -425,24 +425,27 @@ EpisodeListView::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) /* Sort list view items, iSort being the 1-based index of the column * to sort by. If iSort is negative, the order is descending. */ int CALLBACK -ElvSort(LPARAM iItem1, LPARAM iItem2, LPARAM iSort) +ElvSort(LPARAM iItem1, LPARAM iItem2, LPARAM lpLv) { - int iOrder; + EpisodeListView *lpThis = (EpisodeListView *)lpLv; + LVITEM lvi1, lvi2; lvi1.mask = lvi2.mask = LVIF_PARAM; lvi1.iItem = iItem1; lvi2.iItem = iItem2; - if (!ListView_GetItem(HSortLv, &lvi1)) return 0; - if (!ListView_GetItem(HSortLv, &lvi2)) return 0; - iOrder = Cmp(iSort, 0); - switch (abs(iSort)-1) { + if (!ListView_GetItem(lpThis->HWnd(), &lvi1)) return 0; + if (!ListView_GetItem(lpThis->HWnd(), &lvi2)) return 0; + + int iOrder = Cmp(lpThis->ISort(), 0); + + switch (abs(lpThis->ISort())-1) { case ELVSIEPISODE: return iOrder*Cmp(lvi1.lParam, lvi2.lParam); break; case ELVSIRATING: { int iRating1, iRating2; - iRating1 = iSort > 0? 99: -1; - iRating2 = iSort > 0? 99: -1; + iRating1 = lpThis->ISort() > 0? 99: -1; + iRating2 = lpThis->ISort() > 0? 99: -1; Pl("episode_data","episode_rating","Ii",lvi1.lParam,&iRating1); Pl("episode_data","episode_rating","Ii",lvi2.lParam,&iRating2); if (iRating1 == iRating2) diff --git a/c/listview.cpp b/c/listview.cpp index 87b7dbc..09a3024 100644 --- a/c/listview.cpp +++ b/c/listview.cpp @@ -35,13 +35,12 @@ ListView::Create(HMENU hMenu, DWORD dwStyle) int ListView::Height(int bHeader) { - int iCount; - iCount = ListView_GetItemCount(m_hWnd); + int iCount = ListView_GetItemCount(m_hWnd); return iCount? Dpi(bHeader? 27: 4)+iCount*Dpi(19): 0; } HWND -ListView::HWnd() +ListView::HWnd() const { return m_hWnd; } diff --git a/c/main.cpp b/c/main.cpp index 840450e..52fcb42 100644 --- a/c/main.cpp +++ b/c/main.cpp @@ -178,8 +178,7 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) break; case 0x02E0: /* WM_DPICHANGED */ { - LPRECT lpr; - lpr = (LPRECT)lParam; + LPRECT lpr = (LPRECT)lParam; g_iDPI = HIWORD(wParam); SetWindowPos(hWnd, NULL, lpr->left, lpr->top, @@ -212,6 +211,9 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case IDT_TIMER: { static int i = 0; + + /* Animate ellipsis in status bar while doing + * work in other thread. */ if (Pl("episode_data","thread_running","A",g_aThread)) { i = (i+1)%4; SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), @@ -258,28 +260,22 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) break; case IDM_VIEW_WATCHED: { - int iEpFocus; CheckMenuItem(GetMenu(hWnd), IDM_VIEW_WATCHED, g_bViewWatched? MF_UNCHECKED: MF_CHECKED); g_bViewWatched = !g_bViewWatched; - g_elv.Update(); Pl("cfg","set_view_watched","I",g_bViewWatched); - iEpFocus = ListView_GetNextItem(g_elv.HWnd(), -1, LVNI_FOCUSED); - if (iEpFocus == -1) break; - ListView_EnsureVisible(g_elv.HWnd(), iEpFocus, TRUE); + g_elv.Update(); + g_elv.EnsureFocusVisible(); break; } case IDM_VIEW_TV_ORIGINAL: { - int iEpFocus; CheckMenuItem(GetMenu(hWnd), IDM_VIEW_TV_ORIGINAL, g_bViewTVOriginal? MF_UNCHECKED: MF_CHECKED); g_bViewTVOriginal = !g_bViewTVOriginal; - g_elv.Update(); Pl("cfg","set_view_tv_original","I",g_bViewTVOriginal); - iEpFocus = ListView_GetNextItem(g_elv.HWnd(), -1, LVNI_FOCUSED); - if (iEpFocus == -1) break; - ListView_EnsureVisible(g_elv.HWnd(), iEpFocus, TRUE); + g_elv.Update(); + g_elv.EnsureFocusVisible(); break; } case IDM_VIEW_OTHERS: /* Show/hide other screenwriters. */ @@ -290,27 +286,25 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) MF_CHECKED); g_szLimitScreenwriter[0] = 0; } else { - char *sz; - LVITEM lvi; iEpFocus = ListView_GetNextItem(g_elv.HWnd(), -1, LVNI_FOCUSED); if (iEpFocus == -1) break; + + LVITEM lvi; lvi.iItem = iEpFocus; lvi.mask = LVIF_PARAM; if (!ListView_GetItem(g_elv.HWnd(), &lvi)) break; - if (!Pl("episode_data","episode_datum","ISs", - lvi.lParam,"Screenwriter",&sz)) + + char *sz; + if (!Pl("episode_data","episode_datum","ISs",lvi.lParam,"Screenwriter",&sz)) break; strcpy_s(g_szLimitScreenwriter, sizeof(g_szLimitScreenwriter), sz); CheckMenuItem(GetMenu(hWnd), IDM_VIEW_OTHERS, MF_UNCHECKED); } + Pl("cfg","set_limit_screenwriter","S",g_szLimitScreenwriter); g_elv.Update(); - Pl("cfg","set_limit_screenwriter","S", - g_szLimitScreenwriter); - iEpFocus = ListView_GetNextItem(g_elv.HWnd(), -1, LVNI_FOCUSED); - if (iEpFocus == -1) break; - ListView_EnsureVisible(g_elv.HWnd(), iEpFocus, TRUE); + g_elv.EnsureFocusVisible(); break; } case IDM_WATCH_LOCALLY: @@ -456,8 +450,7 @@ AboutDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) HWND CreateStatusBar(HWND hWndParent, HINSTANCE hInstance) { - HWND hWnd; - hWnd = CreateWindowEx( + HWND hWnd = CreateWindowEx( 0, STATUSCLASSNAME, (LPCTSTR) NULL, @@ -485,10 +478,7 @@ Attach() void SetupFonts() { - HMODULE hModule; - LOGFONT lf; - - hModule = LoadLibrary(TEXT("User32.dll")); + HMODULE hModule = LoadLibrary(TEXT("User32.dll")); if (hModule && GetProcAddress(hModule, "SystemParametersInfoW")) { NONCLIENTMETRICS m; m.cbSize = sizeof(NONCLIENTMETRICS); @@ -499,6 +489,8 @@ SetupFonts() } else g_hfNormal = static_cast(GetStockObject(DEFAULT_GUI_FONT)); + + LOGFONT lf; GetObject(g_hfNormal, sizeof(LOGFONT), &lf); lf.lfWeight = FW_BOLD; g_fBold = CreateFontIndirect(&lf); @@ -537,11 +529,8 @@ UpdateLayout() SendMessage(g_dlv.HWnd(), WM_SETREDRAW, TRUE, 0); /* Resize status bar parts. */ - { - int aParts[] = {rc.right-Dpi(55), rc.right}; - SendMessage(g_hWndStatus, SB_SETPARTS, - (WPARAM)sizeof(aParts), (LPARAM)aParts); - } + int aParts[] = {rc.right-Dpi(55), rc.right}; + SendMessage(g_hWndStatus, SB_SETPARTS, (WPARAM)sizeof(aParts), (LPARAM)aParts); } /* Try to style application according to current Windows theme. */ -- cgit v1.2.3