From 4fafc8b49e3f08a87119ef62a54056efba7b6b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Ankarstr=C3=B6m?= Date: Tue, 15 Feb 2022 22:59:58 +0100 Subject: Finish Win32 re-implementation. There are still things to be improved upon, but this commit marks feature parity with the XPCE version. --- c/common.c | 2 +- c/datalistview.c | 1 - c/defs.h | 3 +- c/episodelistview.c | 88 +++++++++++++++++++++++++++++++++++++++-------------- c/main.c | 82 ++++++++++++++++++++++++++++++++++++++----------- c/resource.h | 11 +++++-- c/resource.rc | 11 +++++++ 7 files changed, 152 insertions(+), 46 deletions(-) diff --git a/c/common.c b/c/common.c index c672a4d..a4debc3 100644 --- a/c/common.c +++ b/c/common.c @@ -40,6 +40,6 @@ Watched(int iEpisode) return 0; return PL_call_predicate(NULL, PL_Q_NORMAL, - PL_predicate("watched", 1, "track_episodes"), + PL_predicate("watched", 1, "track_episodes"), t); } diff --git a/c/datalistview.c b/c/datalistview.c index 208ef22..e37375d 100644 --- a/c/datalistview.c +++ b/c/datalistview.c @@ -96,7 +96,6 @@ DlvShowEpisode(int iEpisode) lviKey.iItem = i; lviKey.iSubItem = 0; lviKey.pszText = tszKey; - lviKey.lParam = iEpisode; ListView_InsertItem(hListView, &lviKey); lviValue.iItem = i; diff --git a/c/defs.h b/c/defs.h index 8c808b7..eabc5fc 100644 --- a/c/defs.h +++ b/c/defs.h @@ -17,8 +17,9 @@ HWND LvCreate(HWND, HMENU); /* episodelistview.c */ HWND ElvCreate(HWND); LRESULT ElvHandleNotify(LPARAM); +int ElvItemEpisode(int); void ElvUpdate(void); -void ElvUpdateName(NMLISTVIEW *); +void ElvUpdateName(int, int); /* datalistview.c */ HWND DlvCreate(HWND); diff --git a/c/episodelistview.c b/c/episodelistview.c index 42a2151..e12da4f 100644 --- a/c/episodelistview.c +++ b/c/episodelistview.c @@ -10,7 +10,7 @@ extern HFONT g_GUIFontBold; HWND gElv_hWnd; WNDPROC g_PrevElvProc; -int g_SelectedItem = -1; /* Remembered after refresh. */ +int g_iSelectedItem = -1; /* Remembered after refresh. */ HWND ElvCreate(HWND hWnd) @@ -49,34 +49,76 @@ ElvHandleNotify(LPARAM lParam) case LVN_ITEMCHANGED: if ((pNmLv->uChanged & LVIF_STATE) && (pNmLv->uNewState & LVIS_FOCUSED)) { - g_SelectedItem = pNmLv->iItem; - ElvUpdateName(pNmLv); + g_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; + { + 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 = PL_new_term_refs(1); + if (!PL_put_integer(t+0, ElvItemEpisode(g_iSelectedItem))) + break; + + PL_call_predicate(NULL, PL_Q_NORMAL, + PL_predicate("open_episode", 1, + "local_episodes"), 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, + gElv_hWnd, NULL); + break; + } + } return 0; } +int +ElvItemEpisode(int iItem) { + HWND hListView; + LVITEM lvi; + + hListView = GetDlgItem(gElv_hWnd, IDC_EPISODELISTVIEW); + lvi.mask = LVIF_PARAM; + lvi.iItem = iItem; + lvi.iSubItem = 0; + + if (!ListView_GetItem(hListView, &lvi)) + return -1; + + return lvi.lParam; +} + /* Update episode list. */ void ElvUpdate() @@ -157,10 +199,10 @@ ElvUpdate() free(tszEpisode); } - if (g_SelectedItem != -1) { - ListView_SetItemState(hListView, g_SelectedItem, + if (g_iSelectedItem != -1) { + ListView_SetItemState(hListView, g_iSelectedItem, LVIS_SELECTED, LVIS_SELECTED); - ListView_EnsureVisible(hListView, g_SelectedItem, TRUE); + ListView_EnsureVisible(hListView, g_iSelectedItem, TRUE); } close: @@ -170,7 +212,7 @@ close: /* Update episode name. */ void -ElvUpdateName(NMLISTVIEW *pNmLv) +ElvUpdateName(int iItem, int iEpisode) { char *szName; HWND hListView; @@ -178,7 +220,7 @@ ElvUpdateName(NMLISTVIEW *pNmLv) term_t t; t = PL_new_term_refs(3); - if (!PL_put_integer(t+0, pNmLv->lParam)) + if (!PL_put_integer(t+0, iEpisode)) return; PL_call_predicate(NULL, PL_Q_NORMAL, @@ -193,5 +235,5 @@ ElvUpdateName(NMLISTVIEW *pNmLv) return; hListView = GetDlgItem(gElv_hWnd, IDC_EPISODELISTVIEW); - ListView_SetItemText(hListView, pNmLv->iItem, 1, tszName); + ListView_SetItemText(hListView, iItem, 1, tszName); } diff --git a/c/main.c b/c/main.c index 045d31c..6af1a7f 100644 --- a/c/main.c +++ b/c/main.c @@ -1,7 +1,5 @@ #include #include -#include -#include #include #include "resource.h" @@ -9,6 +7,7 @@ HFONT g_GUIFont; HFONT g_GUIFontBold; +HMENU g_hPopupMenu; static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); static INT_PTR CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM); @@ -43,6 +42,10 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, SetupFonts(); + g_hPopupMenu = LoadMenu(NULL, + MAKEINTRESOURCE(IDR_POPUPMENU)); + g_hPopupMenu = GetSubMenu(g_hPopupMenu, 0); + wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = WndProc; @@ -110,6 +113,54 @@ WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) AboutDlgProc ); break; + case ID_WATCH: + case ID_TOGGLE: + case ID_FORGET: + case ID_LOOKUP: + { + HWND hElv; + int iEpisode; + term_t t; + extern int g_iSelectedItem; + + hElv = GetDlgItem(hWnd, IDC_EPISODELISTVIEW); + iEpisode = ElvItemEpisode(g_iSelectedItem); + + t = PL_new_term_refs(1); + if (!PL_put_integer(t+0, iEpisode)) + break; + + switch (LOWORD(wParam)) { + case ID_WATCH: + PL_call_predicate(NULL, PL_Q_NORMAL, + PL_predicate("open_episode", 1, + "local_episodes"), t); + break; + case ID_TOGGLE: + PL_call_predicate(NULL, PL_Q_NORMAL, + PL_predicate("toggle_episode", 1, + "track_episodes"), t); + ListView_RedrawItems(hElv, + g_iSelectedItem, g_iSelectedItem); + break; + case ID_FORGET: + PL_call_predicate(NULL, PL_Q_NORMAL, + PL_predicate("forget_episode", 1, + "track_episodes"), t); + ListView_RedrawItems(hElv, + g_iSelectedItem, g_iSelectedItem); + break; + case ID_LOOKUP: + PL_call_predicate(NULL, PL_Q_NORMAL, + PL_predicate("retract_episode", 1, + "episode_data"), t); + ElvUpdateName(g_iSelectedItem, iEpisode); + DlvShowEpisode(iEpisode); + ListView_RedrawItems(hElv, + g_iSelectedItem, g_iSelectedItem); + break; + } + } } break; case WM_CREATE: @@ -161,19 +212,18 @@ AboutDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) int Attach() { - int r; term_t t; t = PL_new_term_refs(2); - r = PL_call_predicate(NULL, PL_Q_NORMAL, - PL_predicate("attach", 0, "track_episodes"), - t); - if (!r) return r; + if (!PL_call_predicate(NULL, PL_Q_NORMAL, + PL_predicate("attach", 0, "track_episodes"), + t)) + return 0; - r = PL_call_predicate(NULL, PL_Q_NORMAL, - PL_predicate("attach", 0, "episode_data"), - t); - if (!r) return r; + if (!PL_call_predicate(NULL, PL_Q_NORMAL, + PL_predicate("attach", 0, "episode_data"), + t)) + return 0; return 1; } @@ -209,16 +259,14 @@ UpdateLayout(HWND hWnd) HWND hElv, hDlv; int cxColumn, cyDlv; RECT rc; + extern int g_iSelectedItem; static int cxVScroll = 0; - extern int g_SelectedItem; if (cxVScroll == 0) cxVScroll = GetSystemMetrics(SM_CXVSCROLL); GetClientRect(hWnd, &rc); -#define EDGE 4 - /* Resize data list view. */ hDlv = GetDlgItem(hWnd, IDC_DATALISTVIEW); @@ -229,7 +277,7 @@ UpdateLayout(HWND hWnd) cxColumn = ListView_GetColumnWidth(hDlv, 0); ListView_SetColumnWidth(hDlv, 1, - rc.right-cxColumn-cxVScroll-EDGE); + rc.right-cxColumn-cxVScroll-4); /* Resize episode list view. */ @@ -240,7 +288,7 @@ UpdateLayout(HWND hWnd) cxColumn = ListView_GetColumnWidth(hElv, 0); ListView_SetColumnWidth(hElv, 1, - rc.right-cxColumn-cxVScroll-EDGE); + rc.right-cxColumn-cxVScroll-4); - ListView_EnsureVisible(hElv, g_SelectedItem, TRUE); + ListView_EnsureVisible(hElv, g_iSelectedItem, TRUE); } diff --git a/c/resource.h b/c/resource.h index 16af73e..5893ad4 100644 --- a/c/resource.h +++ b/c/resource.h @@ -2,12 +2,17 @@ #define RESOURCE_H #define IDR_MENU 101 +#define IDR_POPUPMENU 102 #define IDD_ABOUT 201 #define IDC_ABOUTTEXT 301 #define IDC_EPISODELISTVIEW 302 #define IDC_DATALISTVIEW 303 -#define ID_FILE_EXIT 4001 -#define ID_FILE_REFRESH 4002 -#define ID_FILE_ABOUT 4011 +#define ID_FILE_EXIT 401 +#define ID_FILE_REFRESH 402 +#define ID_FILE_ABOUT 411 +#define ID_WATCH 421 +#define ID_TOGGLE 422 +#define ID_FORGET 423 +#define ID_LOOKUP 424 #endif diff --git a/c/resource.rc b/c/resource.rc index bd936bb..7076016 100644 --- a/c/resource.rc +++ b/c/resource.rc @@ -16,6 +16,17 @@ BEGIN END END +IDR_POPUPMENU MENU DISCARDABLE +BEGIN + POPUP "Episode Menu" + BEGIN + MENUITEM "&Watch", ID_WATCH + MENUITEM "&Toggle", ID_TOGGLE + MENUITEM "&Forget", ID_FORGET + MENUITEM "&Lookup", ID_LOOKUP + END +END + #define PAD 7 #define ABOUTW 190 #define ABOUTH 40 -- cgit v1.2.3