diff options
author | John Ankarström <john@ankarstrom.se> | 2022-07-23 22:42:03 +0200 |
---|---|---|
committer | John Ankarström <john@ankarstrom.se> | 2022-07-24 00:30:03 +0200 |
commit | 647fd553af9054b89f4a0d751ea89a98439ae5ac (patch) | |
tree | c8f80284b012a35172c298fcc2950b63238394e1 | |
parent | c6cd2f1f164baac1414f2cf658566de146b10552 (diff) | |
download | EpisodeBrowser-647fd553af9054b89f4a0d751ea89a98439ae5ac.tar.gz |
Improve window layout.
This reverts much of 97f0a27.
1. It turns out not to be a good idea to resize the list view columns
based on the list view window's own rectangle, as it will change
depending on whether a scrollbar is visible. The problem is that
resizing the columns may add a horizontal scrollbar -- which in
turn may add a vertical scrollbar.
2. The WS_EX_CLIENTEDGE style does not look very good in "modern"
(non-classic) themes. In 97f0a27, I tried solving this by extending
the dimensions of the child windows such that their edges were
hidden. However, this type of overlapping causes problems with the
status bar. My new solution is to instead *reduce* the child
windows' dimensions. This achieves a visual impression similar to
the thicker (more well-designed) edges of the "classically themed"
list view control. To make it look even better, the main window
background is changed from COLOR_WINDOWFRAME (white) to
COLOR_WINDOW (light gray).
-rw-r--r-- | c/common.h | 4 | ||||
-rw-r--r-- | c/datalistview.cpp | 9 | ||||
-rw-r--r-- | c/datalistview.h | 2 | ||||
-rw-r--r-- | c/episodelistview.cpp | 11 | ||||
-rw-r--r-- | c/episodelistview.h | 2 | ||||
-rw-r--r-- | c/listview.cpp | 2 | ||||
-rw-r--r-- | c/listview.h | 2 | ||||
-rw-r--r-- | c/main.cpp | 41 | ||||
-rw-r--r-- | c/main.h | 2 |
9 files changed, 36 insertions, 39 deletions
@@ -55,6 +55,10 @@ std::optional<T> maybe_make(U... xs) } } +/* Variable template for caching values from GetSystemMetrics. */ +template <int I> +const auto Metric = GetSystemMetrics(I); + /* Check result of Windows API call, throwing error on NULL. */ template <typename T> inline T require(const T x) diff --git a/c/datalistview.cpp b/c/datalistview.cpp index 1ceeb3b..82b62e6 100644 --- a/c/datalistview.cpp +++ b/c/datalistview.cpp @@ -29,15 +29,12 @@ DataListView::DataListView(const HWND hWndParent) ListView_InsertColumn(hWnd, DLVSIVALUE, &lvc); } -void DataListView::ResizeColumns() +void DataListView::ResizeColumns(int w) { - RECT rc; - require(GetClientRect(hWnd, &rc)); - ListView_SetColumnWidth(hWnd, DLVSIKEY, LVSCW_AUTOSIZE); - const int cxColumn = ListView_GetColumnWidth(hWnd, 0)+4; + const int cxColumn = ListView_GetColumnWidth(hWnd, DLVSIKEY)+Dpi(4); ListView_SetColumnWidth(hWnd, DLVSIKEY, cxColumn); - ListView_SetColumnWidth(hWnd, DLVSIVALUE, rc.right-cxColumn); + ListView_SetColumnWidth(hWnd, DLVSIVALUE, w-cxColumn-Metric<SM_CXVSCROLL>-Dpi(4)); } void DataListView::ShowEpisode(const int iEpisode) diff --git a/c/datalistview.h b/c/datalistview.h index 0bea546..5865ed1 100644 --- a/c/datalistview.h +++ b/c/datalistview.h @@ -9,7 +9,7 @@ struct DataListView : public ListView { DataListView(HWND hWndParent); - void ResizeColumns() override; + void ResizeColumns(int w) override; void ShowEpisode(int iEpisode); }; diff --git a/c/episodelistview.cpp b/c/episodelistview.cpp index bc01ce9..4b93587 100644 --- a/c/episodelistview.cpp +++ b/c/episodelistview.cpp @@ -141,16 +141,13 @@ void EpisodeListView::Redraw() RDW_ERASE|RDW_FRAME|RDW_INVALIDATE|RDW_ALLCHILDREN); } -void EpisodeListView::ResizeColumns() +void EpisodeListView::ResizeColumns(int w) { - RECT rc; - require(GetClientRect(hWnd, &rc)); - ListView_SetColumnWidth(hWnd, ELVSIEPISODE, LVSCW_AUTOSIZE); - int cxColumn = ListView_GetColumnWidth(hWnd, ELVSIEPISODE)+4; + int cxColumn = ListView_GetColumnWidth(hWnd, ELVSIEPISODE)+Dpi(4); ListView_SetColumnWidth(hWnd, ELVSIEPISODE, cxColumn); cxColumn += ListView_GetColumnWidth(hWnd, ELVSIRATING); - ListView_SetColumnWidth(hWnd, ELVSITITLE, rc.right-cxColumn); + ListView_SetColumnWidth(hWnd, ELVSITITLE, w-cxColumn-Metric<SM_CXVSCROLL>-Dpi(4)); } /* Select previously focused episode. */ @@ -406,8 +403,10 @@ void EpisodeListView::Update() if (iItemTopNew != -1) SetTop(iItemTopNew); + /* Show number of displayed items in status bar. */ _stprintf_s(tszDisp, sizeof(tszDisp), TEXT("%d"), iItem); SendMessage(g_hWndStatus, SB_SETTEXT, MAKEWPARAM(1,0), (LPARAM)tszDisp); + SendMessage(hWnd, WM_SETREDRAW, TRUE, 0); } diff --git a/c/episodelistview.h b/c/episodelistview.h index 36ac04b..8747f6b 100644 --- a/c/episodelistview.h +++ b/c/episodelistview.h @@ -16,7 +16,7 @@ struct EpisodeListView : public ListView void EnsureFocusVisible(); LRESULT HandleNotify(LPARAM lParam); void Redraw(); - void ResizeColumns() override; + void ResizeColumns(int w) override; void RestoreFocus(); void SaveFocus(); void SetTop(int iItem); diff --git a/c/listview.cpp b/c/listview.cpp index 5418e33..622ff87 100644 --- a/c/listview.cpp +++ b/c/listview.cpp @@ -38,7 +38,7 @@ int ListView::Height(int bHeader) return iCount? Dpi(bHeader? 27: 4)+iCount*Dpi(19): 0; } -void ListView::ResizeColumns() {} +void ListView::ResizeColumns(int) {} void ListView::UpdateTheme(const BOOL bThemeActive) { diff --git a/c/listview.h b/c/listview.h index 528ddc3..478819f 100644 --- a/c/listview.h +++ b/c/listview.h @@ -9,7 +9,7 @@ struct ListView ListView(HWND hWndParent, HMENU hMenu, DWORD dwStyle); int Height(int bHeader = -1); - virtual void ResizeColumns(); + virtual void ResizeColumns(int w); virtual void UpdateTheme(BOOL bThemeActive); virtual LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); protected: @@ -107,7 +107,7 @@ int WINAPI WinMain(const HINSTANCE hInstance, const HINSTANCE, char* const, cons wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); - wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wc.hbrBackground = (HBRUSH)COLOR_WINDOW; wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU); wc.lpszClassName = TEXT("Episode Browser"); wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); @@ -207,7 +207,7 @@ LRESULT CALLBACK WndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam, switch (uMsg) { case WM_CREATE: UpdateTheme(); - SetWindowPos(hWnd, NULL, -1, -1, Dpi(510), Dpi(400), SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE); + SetWindowPos(hWnd, NULL, -1, -1, Dpi(510), Dpi(412), SWP_NOZORDER|SWP_NOMOVE|SWP_NOACTIVATE); SetFocus(g_pElv->hWnd); /* Set menu item checkmarks according to saved settings. */ @@ -227,7 +227,7 @@ LRESULT CALLBACK WndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam, break; case WM_SIZE: SendMessage(g_hWndStatus, WM_SIZE, wParam, lParam); - UpdateLayout(); + UpdateLayout(LOWORD(lParam), HIWORD(lParam)); break; case WM_GETMINMAXINFO: { @@ -248,7 +248,7 @@ LRESULT CALLBACK WndProc(const HWND hWnd, const UINT uMsg, const WPARAM wParam, lpr->right-lpr->left, lpr->bottom-lpr->top, SWP_NOZORDER|SWP_NOACTIVATE)); - UpdateLayout(); + UpdateLayout(lpr->right-lpr->left, lpr->bottom-lpr->top); break; } case WM_ACTIVATE: @@ -506,35 +506,32 @@ INT_PTR CALLBACK AboutDlgProc(const HWND hWnd, const UINT uMsg, const WPARAM wPa return TRUE; } -void UpdateLayout() +void UpdateLayout(int w, int h) { if (!g_hWndStatus) return; RECT rc, rrStatus; - require(GetClientRect(g_hWnd, &rc)); + if (w && h) rc = {0, 0, w, h}; + else require(GetClientRect(g_hWnd, &rc)); require(GetRelativeRect(g_hWndStatus, &rrStatus)); - /* Resize list views. */ - SendMessage(g_pDlv->hWnd, WM_SETREDRAW, FALSE, 0); - SendMessage(g_pElv->hWnd, WM_SETREDRAW, FALSE, 0); - - /* If a modern theme is used, list view borders should be - * hidden. This variable governs that. (See how it is used in - * the arguments to SetWindowRect below.) */ - const long x = IsThemeActive(); - - const long cyDlv = rrStatus.top-g_pDlv->Height(); - require(SetWindowRect(g_pDlv->hWnd, -x, cyDlv, rc.right+x*2, rrStatus.top+x)); - require(SetWindowRect(g_pElv->hWnd, -x, -x*2, rc.right+x*2, cyDlv+x)); - g_pDlv->ResizeColumns(); - g_pElv->ResizeColumns(); + SendMessage(g_hWnd, WM_SETREDRAW, FALSE, 0); - SendMessage(g_pElv->hWnd, WM_SETREDRAW, TRUE, 0); - SendMessage(g_pDlv->hWnd, WM_SETREDRAW, TRUE, 0); + /* Resize list views. */ + const long pad = IsThemeActive()? Dpi(6): 0; /* Add padding in modern themes. */ + const long cyDlv = rrStatus.top-g_pDlv->Height()-pad; + require(SetWindowRect(g_pDlv->hWnd, pad, cyDlv, rc.right-pad, rrStatus.top-pad)); + require(SetWindowRect(g_pElv->hWnd, pad, pad, rc.right-pad, cyDlv-pad)); + g_pDlv->ResizeColumns(rc.right-pad-pad); + g_pElv->ResizeColumns(rc.right-pad-pad); /* Resize status bar parts. */ const int aParts[] = {rc.right-Dpi(55), rc.right}; SendMessage(g_hWndStatus, SB_SETPARTS, (WPARAM)sizeof(aParts), (LPARAM)aParts); + + SendMessage(g_hWnd, WM_SETREDRAW, TRUE, 0); + RedrawWindow(g_hWnd, NULL, NULL, + RDW_ERASE|RDW_FRAME|RDW_INVALIDATE|RDW_ALLCHILDREN); } /* Try to style application according to current Windows theme. */ @@ -1,6 +1,6 @@ #ifndef MAIN_H #define MAIN_H -void UpdateLayout(); +void UpdateLayout(int w = 0, int h = 0); #endif |