From d9b9a9a74346c4933a11e2369d56a22cf51b12aa Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Sun, 17 Aug 2014 17:22:47 -0400 Subject: [PATCH] Implemented hover-to-hot on Windows Table checkboxes. --- redo/table_windows.c | 20 ++++++++++++++++++++ redo/table_windows.go | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/redo/table_windows.c b/redo/table_windows.c index 775d4e6..357da25 100644 --- a/redo/table_windows.c +++ b/redo/table_windows.c @@ -6,6 +6,22 @@ // provided for cgo's benefit LPWSTR xWC_LISTVIEW = WC_LISTVIEW; +static void handleMouseMove(HWND hwnd, WPARAM wParam, LPARAM lParam, void *data) +{ + LVHITTESTINFO ht; + + // TODO use wParam + ZeroMemory(&ht, sizeof (LVHITTESTINFO)); + ht.pt.x = GET_X_LPARAM(lParam); + ht.pt.y = GET_Y_LPARAM(lParam); + ht.flags = LVHT_ONITEMSTATEICON; + if (SendMessageW(hwnd, LVM_SUBITEMHITTEST, 0, (LPARAM) (&ht)) == (LRESULT) -1) { + tableSetHot(data, -1, -1); + return; // no item + } + tableSetHot(data, ht.iItem, ht.iSubItem); +} + static LRESULT CALLBACK tableSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR id, DWORD_PTR data) { NMHDR *nmhdr = (NMHDR *) lParam; @@ -19,6 +35,10 @@ static LRESULT CALLBACK tableSubProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM return 0; } return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam); + case WM_MOUSEMOVE: + handleMouseMove(hwnd, wParam, lParam, (void *) data); + // and let the list view do its thing + return (*fv_DefSubclassProc)(hwnd, uMsg, wParam, lParam); // see table.autoresize() in table_windows.go for the column autosize policy case WM_NOTIFY: // from the contained header control if (nmhdr->code == HDN_BEGINTRACK) diff --git a/redo/table_windows.go b/redo/table_windows.go index c90a6fa..83e6cd1 100644 --- a/redo/table_windows.go +++ b/redo/table_windows.go @@ -16,6 +16,8 @@ type table struct { _hwnd C.HWND noautosize bool colcount C.int + hotrow C.int + hotcol C.int } func finishNewTable(b *tablebase, ty reflect.Type) Table { @@ -24,6 +26,8 @@ func finishNewTable(b *tablebase, ty reflect.Type) Table { C.LVS_REPORT | C.LVS_OWNERDATA | C.LVS_NOSORTHEADER | C.LVS_SHOWSELALWAYS | C.WS_HSCROLL | C.WS_VSCROLL | C.WS_TABSTOP, C.WS_EX_CLIENTEDGE), // WS_EX_CLIENTEDGE without WS_BORDER will show the canonical visual styles border (thanks to MindChild in irc.efnet.net/#winprog) tablebase: b, + hotrow: -1, + hotcol: -1, } C.setTableSubclass(t._hwnd, unsafe.Pointer(t)) // LVS_EX_FULLROWSELECT gives us selection across the whole row, not just the leftmost column; this makes the list view work like on other platforms @@ -77,6 +81,11 @@ func tableGetCell(data unsafe.Pointer, item *C.LVITEMW) { } else { curstate &^= C.checkboxStateChecked } + if item.iItem == t.hotrow && item.iSubItem == t.hotcol { + curstate |= C.checkboxStateHot + } else { + curstate &^= C.checkboxStateHot + } item.state = (curstate + 1) << 12 default: s := fmt.Sprintf("%v", datum) @@ -106,6 +115,17 @@ func tableColumnCount(data unsafe.Pointer) C.int { return t.colcount } +//export tableSetHot +func tableSetHot(data unsafe.Pointer, row C.int, col C.int) { + t := (*table)(data) + redraw := (row != t.hotrow || col != t.hotcol) + t.hotrow = row + t.hotcol = col + if redraw { + C.tableUpdate(t._hwnd, C.int(reflect.Indirect(reflect.ValueOf(t.data)).Len())) + } +} + func (t *table) hwnd() C.HWND { return t._hwnd }