And rewired the focus rect.

This commit is contained in:
Pietro Gagliardi 2018-06-21 23:47:24 -04:00
parent c2000ea54d
commit d0f7cf81c5
1 changed files with 31 additions and 34 deletions

View File

@ -2,6 +2,9 @@
#include "uipriv_windows.hpp" #include "uipriv_windows.hpp"
#include "table.hpp" #include "table.hpp"
// TODOs:
// - properly hide selection when not focused (or switch on LVS_SHOWSELALWAYS and draw that state)
// TODO // TODO
#define cellValue(model, row, column) ((*((model)->mh->CellValue))((model)->mh, (model), (row), (column))) #define cellValue(model, row, column) ((*((model)->mh->CellValue))((model)->mh, (model), (row), (column)))
@ -608,49 +611,33 @@ fail:
return hr; return hr;
} }
// TODO this has overdraw issues on non-selected rows; do they happen on selected rows too? static HRESULT updateAndDrawFocusRects(uiTable *t, HDC dc, int iItem, RECT *realTextBackground, RECT *focus, bool *first)
static HRESULT drawFocusRects(uiTable *t, NMLVCUSTOMDRAW *nm)
{ {
RECT r; LRESULT state;
bool first;
size_t i, n;
uiprivTableMetrics *m;
HRESULT hr;
// TODO check error here?
if (GetFocus() != t->hwnd) if (GetFocus() != t->hwnd)
return S_OK; return S_OK;
// TODO only if the current item is focused // uItemState CDIS_FOCUS doesn't quite work right because of bugs in the Windows list view that causes spurious redraws without the flag while we hover over the focused item
// TODO only call this once
state = SendMessageW(t->hwnd, LVM_GETITEMSTATE, (WPARAM) iItem, (LRESULT) (LVIS_FOCUSED));
if ((state & LVIS_FOCUSED) == 0)
return S_OK;
ZeroMemory(&r, sizeof (RECT)); if (realTextBackground != NULL)
first = true; if (*first) {
n = t->columns->size(); *focus = *realTextBackground;
for (i = 0; i < n; i++) {
RECT b;
hr = uiprivTableGetMetrics(t, nm->nmcd.dwItemSpec, i, &m);
if (hr != S_OK)
return hr;
b = m->realTextBackground;
uiprivFree(m);
if (first) {
r = b;
first = false; first = false;
} else if (r.right == b.left) return S_OK;
r.right = b.right; } else if (focus->right == realTextBackground->left) {
else { focus->right = realTextBackground->right;
if (DrawFocusRect(nm->nmcd.hdc, &r) == 0) { return S_OK;
logLastError(L"DrawFocusRect()");
return E_FAIL;
}
r = b;
} }
} if (DrawFocusRect(dc, focus) == 0) {
// and draw the last rect logLastError(L"DrawFocusRect()");
if (DrawFocusRect(nm->nmcd.hdc, &r) == 0) {
logLastError(L"DrawFocusRect() last");
return E_FAIL; return E_FAIL;
} }
if (realTextBackground != NULL)
*focus = *realTextBackground;
return S_OK; return S_OK;
} }
@ -667,6 +654,8 @@ HRESULT uiprivTableHandleNM_CUSTOMDRAW(uiTable *t, NMLVCUSTOMDRAW *nm, LRESULT *
uiprivTableColumnParams *p; uiprivTableColumnParams *p;
NMLVCUSTOMDRAW b; NMLVCUSTOMDRAW b;
size_t i, n; size_t i, n;
RECT focus;
bool focusFirst;
HRESULT hr; HRESULT hr;
switch (nm->nmcd.dwDrawStage) { switch (nm->nmcd.dwDrawStage) {
@ -682,6 +671,7 @@ HRESULT uiprivTableHandleNM_CUSTOMDRAW(uiTable *t, NMLVCUSTOMDRAW *nm, LRESULT *
n = t->columns->size(); n = t->columns->size();
b = *nm; b = *nm;
focusFirst = false;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
b.iSubItem = i; b.iSubItem = i;
p = (*(t->columns))[i]; p = (*(t->columns))[i];
@ -704,12 +694,19 @@ HRESULT uiprivTableHandleNM_CUSTOMDRAW(uiTable *t, NMLVCUSTOMDRAW *nm, LRESULT *
if (hr != S_OK) if (hr != S_OK)
goto fail; goto fail;
hr = drawButtonPart(&s); hr = drawButtonPart(&s);
if (hr != S_OK)
goto fail;
hr = updateAndDrawFocusRects(s.t, s.dc, nm->nmcd.dwItemSpec, &(s.m->realTextBackground), &focus, &focusFirst);
if (hr != S_OK) if (hr != S_OK)
goto fail; goto fail;
hr = freeDrawState(&s); hr = freeDrawState(&s);
if (hr != S_OK) // TODO really error out here? if (hr != S_OK) // TODO really error out here?
return hr; return hr;
} }
// and draw the last focus rect
hr = updateAndDrawFocusRects(t, nm->nmcd.hdc, nm->nmcd.dwItemSpec, NULL, &focus, &focusFirst);
if (hr != S_OK)
return hr;
*lResult = CDRF_SKIPDEFAULT; *lResult = CDRF_SKIPDEFAULT;
return S_OK; return S_OK;
fail: fail: