Tried to combine all the Windows table metrics stuff. This broke things, so we'll have to go back to the drawing board here.

This commit is contained in:
Pietro Gagliardi 2018-06-11 22:22:54 -04:00
parent c843f1e62d
commit 8f0019af10
1 changed files with 153 additions and 0 deletions

153
wintablemetrics Normal file
View File

@ -0,0 +1,153 @@
diff --git a/windows/table.cpp b/windows/table.cpp
index 32c60244..d33cb22f 100644
--- a/windows/table.cpp
+++ b/windows/table.cpp
@@ -137,11 +137,71 @@ static COLORREF blend(COLORREF base, double r, double g, double b, double a)
(BYTE) (bb * 255));
}
+static HRESULT fillSubitemDrawParams(HWND hwnd, NMLVCUSTOMDRAW *nm, uiprivSubitemDrawParams *dp)
+{
+ RECT r;
+ HRESULT hr;
+
+ // note that we can't just copy nm->nmcd.rc into p->bounds because that is only defined during prepaint stages
+
+ if (nm->iSubItem == 0) {return S_OK;
+ ZeroMemory(&r, sizeof (RECT));
+ r.left = LVIR_BOUNDS;
+ if (SendMessageW(hwnd, LVM_GETITEMRECT, nm->nmcd.dwItemSpec, (LPARAM) (&r)) == FALSE) {
+ logLastError(L"LVM_GETITEMRECT LVIR_BOUNDS");
+ return E_FAIL;
+ }
+ dp->bounds = r;
+ ZeroMemory(&r, sizeof (RECT));
+ r.left = LVIR_ICON;
+ if (SendMessageW(hwnd, LVM_GETITEMRECT, nm->nmcd.dwItemSpec, (LPARAM) (&r)) == FALSE) {
+ logLastError(L"LVM_GETITEMRECT LVIR_ICON");
+ return E_FAIL;
+ }
+ dp->icon = r;
+ ZeroMemory(&r, sizeof (RECT));
+ r.left = LVIR_LABEL;
+ if (SendMessageW(hwnd, LVM_GETITEMRECT, nm->nmcd.dwItemSpec, (LPARAM) (&r)) == FALSE) {
+ logLastError(L"LVM_GETITEMRECT LVIR_LABEL");
+ return E_FAIL;
+ }
+ dp->label = r;
+ return S_OK;
+ }
+
+ ZeroMemory(&r, sizeof (RECT));
+ r.left = LVIR_BOUNDS;
+ r.top = nm->iSubItem;
+ if (SendMessageW(hwnd, LVM_GETSUBITEMRECT, nm->nmcd.dwItemSpec, (LPARAM) (&r)) == 0) {
+ logLastError(L"LVM_GETSUBITEMRECT LVIR_BOUNDS");
+ return E_FAIL;
+ }
+ dp->bounds = r;
+ ZeroMemory(&r, sizeof (RECT));
+ r.left = LVIR_ICON;
+ r.top = nm->iSubItem;
+ if (SendMessageW(hwnd, LVM_GETSUBITEMRECT, nm->nmcd.dwItemSpec, (LPARAM) (&r)) == 0) {
+ logLastError(L"LVM_GETSUBITEMRECT LVIR_ICON");
+ return E_FAIL;
+ }
+ dp->icon = r;
+ // LVIR_LABEL is treated as LVIR_BOUNDS for LVM_GETSUBITEMRECT, but it doesn't matter because the label rect is uses isn't what we want anyway
+ // there's a hardocded 2-logical unit gap between the icon and text for subitems, AND the text starts being drawn (in the background) one bitmap margin to the right of that
+ // with normal items, there's no gap, and only the 2-logical unit gap after the background starts (TODO confirm this part)
+ // let's copy that to look nicer, even if it's not "accurate"
+ // TODO check against accessibility
+ dp->label = dp->bounds;
+ // because we want the 2 extra logical units to be included with the background, we don't include them here
+ dp->label.left = dp->icon.right;
+ return S_OK;
+}
+
static LRESULT onNM_CUSTOMDRAW(uiTable *t, NMLVCUSTOMDRAW *nm)
{
uiprivTableColumnParams *p;
uiTableData *data;
double r, g, b, a;
+ uiprivSubitemDrawParams dp;
LRESULT ret;
HRESULT hr;
@@ -193,7 +253,12 @@ DrawTextW(nm->nmcd.hdc, L"Part", -1,
ret = CDRF_DODEFAULT;
}
- hr = uiprivNM_CUSTOMDRAWImagesCheckboxes(t, nm, &ret);
+ ZeroMemory(&dp, sizeof (uiprivSubitemDrawParams));
+ hr = fillSubitemDrawParams(t->hwnd, nm, &dp);
+ if (hr != S_OK) {
+ // TODO
+ }
+ hr = uiprivNM_CUSTOMDRAWImagesCheckboxes(t, nm, &dp, &ret);
if (hr != S_OK) {
// TODO
}
diff --git a/windows/table.hpp b/windows/table.hpp
index 0be01d8f..2f4f6936 100644
--- a/windows/table.hpp
+++ b/windows/table.hpp
@@ -43,8 +43,14 @@ struct uiTable {
// custom draw state
COLORREF clrItemText;
};
+typedef struct uiprivSubitemDrawParams uiprivSubitemDrawParams;
+struct uiprivSubitemDrawParams {
+ RECT bounds;
+ RECT icon;
+ RECT label;
+};
// tableimages.cpp
extern HRESULT uiprivLVN_GETDISPINFOImagesCheckboxes(uiTable *t, NMLVDISPINFOW *nm, uiprivTableColumnParams *p);
-extern HRESULT uiprivNM_CUSTOMDRAWImagesCheckboxes(uiTable *t, NMLVCUSTOMDRAW *nm, LRESULT *lResult);
+extern HRESULT uiprivNM_CUSTOMDRAWImagesCheckboxes(uiTable *t, NMLVCUSTOMDRAW *nm, uiprivSubitemDrawParams *dp, LRESULT *lResult);
extern HRESULT uiprivTableSetupImagesCheckboxes(uiTable *t);
diff --git a/windows/tableimages.cpp b/windows/tableimages.cpp
index a42307b1..14bae8c8 100644
--- a/windows/tableimages.cpp
+++ b/windows/tableimages.cpp
@@ -139,12 +139,11 @@ HRESULT uiprivLVN_GETDISPINFOImagesCheckboxes(uiTable *t, NMLVDISPINFOW *nm, uip
// however, there seems to be no way to do this natively, so we have to draw over ourselves (TODO?)
// hopefully the performance won't be too bad
// see also https://www.codeproject.com/Articles/79/Neat-Stuff-to-Do-in-List-Controls-Using-Custom-Dra
-HRESULT uiprivNM_CUSTOMDRAWImagesCheckboxes(uiTable *t, NMLVCUSTOMDRAW *nm, LRESULT *lResult)
+HRESULT uiprivNM_CUSTOMDRAWImagesCheckboxes(uiTable *t, NMLVCUSTOMDRAW *nm, uiprivSubitemDrawParams *dp, LRESULT *lResult)
{
uiprivTableColumnParams *p;
int index;
RECT r;
- RECT cellRect;
LONG yoff;
if (nm->nmcd.dwDrawStage == (CDDS_SUBITEM | CDDS_ITEMPREPAINT)) {
@@ -161,22 +160,9 @@ HRESULT uiprivNM_CUSTOMDRAWImagesCheckboxes(uiTable *t, NMLVCUSTOMDRAW *nm, LRES
index = checkboxIndex(t->model, nm->nmcd.dwItemSpec,
p->checkboxModelColumn, p->checkboxEditableColumn);
- ZeroMemory(&r, sizeof (RECT));
- r.left = LVIR_ICON;
- r.top = nm->iSubItem;
- if (SendMessageW(t->hwnd, LVM_GETSUBITEMRECT, nm->nmcd.dwItemSpec, (LPARAM) (&r)) == 0) {
- logLastError(L"LVM_GETSUBITEMRECT");
- return E_FAIL;
- }
+ r = dp->icon;
// the real listview also does this :|
- ZeroMemory(&cellRect, sizeof (RECT));
- r.left = LVIR_BOUNDS;
- r.top = nm->iSubItem;
- if (SendMessageW(t->hwnd, LVM_GETSUBITEMRECT, nm->nmcd.dwItemSpec, (LPARAM) (&cellRect)) == 0) {
- logLastError(L"LVM_GETSUBITEMRECT cell");
- return E_FAIL;
- }
- yoff = ((cellRect.bottom - cellRect.top) - (r.bottom - r.top)) / 2;
+ yoff = ((dp->bounds.bottom - dp->bounds.top) - (r.bottom - r.top)) / 2;
r.top += yoff;
r.bottom += yoff;
if ((nm->nmcd.dwItemSpec%2)==0)