diff --git a/wintable/new/events.h b/wintable/new/events.h index a631178..edef132 100644 --- a/wintable/new/events.h +++ b/wintable/new/events.h @@ -1,6 +1,7 @@ // 5 december 2014 static const handlerfunc keyDownHandlers[] = { + keyDownSelectHandler, NULL, }; diff --git a/wintable/new/select.h b/wintable/new/select.h index 8f23f03..72cf2da 100644 --- a/wintable/new/select.h +++ b/wintable/new/select.h @@ -92,6 +92,10 @@ the routine below is intended to simulate the comctl32.dll listview keyboard nav horizontal scrolling is different because unlike the comctl32 listview, we say that a single column in each row has the keyboard focus, so left and right navigate between columns here, instead of scrolling left/right by pixels. TODO provide an override for scrolling by pixels? TODO any other keyboard shortcuts? + TODO browser keys + TODO media navigation keys + TODO XBUTTON1/2? + TODO clear keys? keyboard selection behaviors of the windows 7 listview: with 100 items (0-99), the window currently shows items 30 through 47 as well as having item 48 partially visible @@ -125,3 +129,93 @@ when nothing is selected: for left and right we will simulate up and down, respectively (so right selects row 0 column 0); remember that you can't have either row or column be -1 but not both */ + +HANDLER(keyDownSelectHandler) +{ + intptr_t row; + intptr_t column; + + if (t->count == 0 || t->nColumns == 0) // no items to select + return FALSE; + row = t->selectedRow; + column = t->selectedColumn; + switch (wParam) { + case VK_UP: + if (row == -1) + return FALSE; + row--; + if (row < 0) + row = 0; + break; + case VK_DOWN: + if (row == -1) { + row = 0; + column = 0; + } else { + row++; + if (row > t->count - 1) + row = t->count - 1; + } + break; + case VK_LEFT: + if (column == -1) + return FALSE; + column--; + if (column < 0) + column = 0; + break; + case VK_RIGHT: + if (column == -1) { + row = 0; + column = 0; + } else { + column++; + if (column > t->nColumns - 1) + column = t->nColumns - 1; + } + break; + case VK_HOME: + row = 0; + if (column == -1) + column = 0; + break; + case VK_END: + row = t->count - 1; + if (column == -1) + column = 0; + break; + case VK_PRIOR: + if (row == -1) { + row = 0; + column = 0; + } else { + row = t->vscrollpos; + if (row == t->selectedRow) + // TODO investigate why the - 1 is needed here and below + // TODO if this is a misunderstanding of how t->vpagesize works, figure out what happens if there is no partially visible row, and what is supposed to happen + row -= t->vpagesize - 1; + if (row < 0) + row = 0; + } + break; + case VK_NEXT: + if (row == -1) { + row = t->vpagesize; + column = 0; + } else { + row = t->vscrollpos + t->vpagesize - 1; + if (row == t->selectedRow) + row += t->vpagesize - 1; + if (row > t->count - 1) + row = t->count - 1; + } + break; + default: + return FALSE; + } + doselect(t, row, column); + *lResult = 0; + return TRUE; +} + +// TODO check keyboard selections with nothing selected