summaryrefslogtreecommitdiff
path: root/prev/wintable/select.h
diff options
context:
space:
mode:
Diffstat (limited to 'prev/wintable/select.h')
-rw-r--r--prev/wintable/select.h269
1 files changed, 0 insertions, 269 deletions
diff --git a/prev/wintable/select.h b/prev/wintable/select.h
deleted file mode 100644
index 6ece240..0000000
--- a/prev/wintable/select.h
+++ /dev/null
@@ -1,269 +0,0 @@
-// 13 december 2014
-
-// damn winsock
-static void doselect(struct table *t, intptr_t row, intptr_t column)
-{
- RECT r, client;
- intptr_t oldrow;
- LONG width, height;
- struct rowcol rc;
- BOOL dovscroll;
- intptr_t i;
- intptr_t xpos;
- LONG clientWidth;
-
- // check existing selection to see if it's valid
- if (t->selectedRow == -1 && t->selectedColumn != -1)
- panic("sanity check failure: old Table selection invalid (row == -1, column != -1)");
- if (t->selectedRow != -1 && t->selectedColumn == -1)
- panic("sanity check failure: old Table selection invalid (row != -1, column == -1)");
- if (t->selectedRow >= t->count)
- panic("sanity check failure: old Table selection invalid (row out of range)");
- if (t->selectedColumn >= t->nColumns)
- panic("sanity check failure: old Table selection invalid (column out of range)");
-
- oldrow = t->selectedRow;
- t->selectedRow = row;
- t->selectedColumn = column;
-
- // check new selection to see if it's valid
- if (t->selectedRow == -1 && t->selectedColumn != -1)
- panic("sanity check failure: new Table selection invalid (row == -1, column != -1)");
- if (t->selectedRow != -1 && t->selectedColumn == -1)
- panic("sanity check failure: new Table selection invalid (row != -1, column == -1)");
- if (t->selectedRow >= t->count)
- panic("sanity check failure: new Table selection invalid (row out of range)");
- if (t->selectedColumn >= t->nColumns)
- panic("sanity check failure: new Table selection invalid (column out of range)");
-
- // do this even if we don't scroll before; noScroll depends on it
- if (GetClientRect(t->hwnd, &client) == 0)
- panic("error getting Table client rect in doselect()");
- client.top += t->headerHeight;
- height = rowht(t);
-
- // only scroll if we selected something
- if (t->selectedRow == -1 || t->selectedColumn == -1)
- goto noScroll;
-
- // first vertically scroll to the new row to make it fully visible (or as visible as possible)
- if (t->selectedRow < t->vscrollpos)
- vscrollto(t, t->selectedRow);
- else {
- rc.row = t->selectedRow;
- rc.column = t->selectedColumn;
- // first assume entirely outside the client area
- dovscroll = TRUE;
- if (rowColumnToClientRect(t, rc, &r))
- // partially outside the client area?
- if (r.bottom <= client.bottom) // <= here since we are comparing bottoms (which are the first pixels outside the rectangle)
- dovscroll = FALSE;
- if (dovscroll)
- vscrollto(t, t->selectedRow - t->vpagesize + 1); // + 1 because apparently just t->selectedRow - t->vpagesize results in no scrolling (t->selectedRow - t->vpagesize == t->vscrollpos)...
- }
-
- // now see if the cell we want is to the left of offscreen, in which case scroll to its x-position
- xpos = 0;
- for (i = 0; i < t->selectedColumn; i++)
- xpos += columnWidth(t, i);
- if (xpos < t->hscrollpos)
- hscrollto(t, xpos);
- else {
- // if the full cell is not visible, scroll to the right just enough to make it fully visible (or as visible as possible)
- width = columnWidth(t, t->selectedColumn);
- clientWidth = client.right - client.left;
- if (xpos + width > t->hscrollpos + clientWidth) // > because both sides deal with the first pixel outside
- // if the column is too wide, then just make it occupy the whole visible area (left-aligned)
- if (width > clientWidth) // TODO >= ?
- hscrollto(t, xpos);
- else
- // TODO don't use t->hpagesize here? depends if other code uses it
- hscrollto(t, (xpos + width) - t->hpagesize);
- }
-
-noScroll:
- // now redraw the old and new /rows/
- // we do this after scrolling so the rectangles to be invalidated make sense
- r.left = client.left;
- r.right = client.right;
- if (oldrow != -1 && oldrow >= t->vscrollpos) {
- r.top = client.top + ((oldrow - t->vscrollpos) * height);
- r.bottom = r.top + height;
- if (InvalidateRect(t->hwnd, &r, TRUE) == 0)
- panic("error queueing previously selected row for redraw in doselect()");
- }
- // t->selectedRow must be visible by this point; we scrolled to it
- if (t->selectedRow != -1 && t->selectedRow != oldrow) {
- r.top = client.top + ((t->selectedRow - t->vscrollpos) * height);
- r.bottom = r.top + height;
- if (InvalidateRect(t->hwnd, &r, TRUE) == 0)
- panic("error queueing newly selected row for redraw in doselect()");
- }
-
- // TODO what about deselect/defocus?
- // TODO notify on the old row too?
- NotifyWinEvent(EVENT_OBJECT_SELECTION, t->hwnd, OBJID_CLIENT, t->selectedRow);
- // TODO send EVENT_OBJECT_STATECHANGED too?
- // TODO send EVENT_OBJECT_FOCUS
-
- // TODO before or after NotifyWinEvent()? (see what other things I'm doing)
- notify(t, tableNotificationSelectionChanged, t->selectedRow, t->selectedColumn, 0);
-}
-
-// TODO make this needless
-HANDLER(checkboxMouseDownHandler);
-
-// TODO which WM_xBUTTONDOWNs?
-HANDLER(mouseDownSelectHandler)
-{
- struct rowcol rc;
-
- // TODO separate this from here
- // TODO other mouse buttons?
- // don't check SetFocus()'s error (http://stackoverflow.com/questions/24073695/winapi-can-setfocus-return-null-without-an-error-because-thats-what-im-see)
- // TODO NotifyWinEvent() here?
- SetFocus(t->hwnd);
- rc = lParamToRowColumn(t, lParam);
- // don't check if lParamToRowColumn() returned row -1 or column -1; we want deselection behavior
- doselect(t, rc.row, rc.column);
- // TODO separate this from here
- checkboxMouseDownHandler(t, uMsg, wParam, lParam, lResult);
- *lResult = 0;
- return TRUE;
-}
-
-/*
-the routine below is intended to simulate the comctl32.dll listview keyboard navigation rules, at least as far as vertical navigation is concerned.
-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
-- item 30:
- - page up -> item 13
- - page down -> item 47
-- item 31:
- - page up -> item 30
- - page down -> item 47
-- item 42:
- - page up -> item 30
- - page down -> item 47
-- item 46:
- - page up -> item 30
- - page down -> item 47
-- item 47:
- - page up: -> item 30
- - page down: -> item 64
-
-when nothing is selected:
-- down selects item 0 regardless of scroll
-- up selects nothing regardless of scroll
-- page down selects the last fully visible item depending on scroll
- - so with the above configuration:
- - item 0 -> item 17
- - item 30 -> item 47
- - item 80 -> item 97
-- page up selects item 0 regardless of scroll
-- home selects item 0 regardless of scroll
-- end selects the last item regardless of scroll
-
-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
-
-TODO what happens if page up and page down are pressed with an item selected and the scroll in a different position?
-*/
-
-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)
- 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)
- 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->vscrollpos + t->vpagesize - 1;
- // TODO ensusre this is the case with the real list view
- if (row >= t->count)
- row = t->count - 1;
- column = 0;
- } else {
- row = t->vscrollpos + t->vpagesize - 1;
- if (row == t->selectedRow)
- row += t->vpagesize - 1;
- if (row >= t->count)
- row = t->count - 1;
- }
- break;
- default:
- return FALSE;
- }
- doselect(t, row, column);
- *lResult = 0;
- return TRUE;
-}