summaryrefslogtreecommitdiff
path: root/wintable/main.c
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2014-11-29 18:29:50 -0500
committerPietro Gagliardi <[email protected]>2014-11-29 18:29:50 -0500
commitd23cdd76827728a4f7eb6b0afa9b6e572aab964c (patch)
tree71cb46d964c339d5a8f8b179ad0d8e2f102dcc72 /wintable/main.c
parent6cce68074a84e903b42032e2e972d551205c147f (diff)
Started splitting the new Windows Table code into more manageable chunks.
Diffstat (limited to 'wintable/main.c')
-rw-r--r--wintable/main.c371
1 files changed, 4 insertions, 367 deletions
diff --git a/wintable/main.c b/wintable/main.c
index 6618f50..1349889 100644
--- a/wintable/main.c
+++ b/wintable/main.c
@@ -93,373 +93,10 @@ struct table {
int checkboxHeight;
};
-static LONG rowHeight(struct table *t)
-{
- HFONT thisfont, prevfont;
- TEXTMETRICW tm;
- HDC dc;
- LONG ret;
-
- dc = GetDC(t->hwnd);
- if (dc == NULL)
- abort();
- thisfont = t->font; // in case WM_SETFONT happens before we return
- prevfont = (HFONT) SelectObject(dc, thisfont);
- if (prevfont == NULL)
- abort();
- if (GetTextMetricsW(dc, &tm) == 0)
- abort();
- if (SelectObject(dc, prevfont) != (HGDIOBJ) (thisfont))
- abort();
- if (ReleaseDC(t->hwnd, dc) == 0)
- abort();
- ret = tm.tmHeight;
- if (ret < t->imagelistHeight)
- ret = t->imagelistHeight;
- if (ret < t->checkboxHeight)
- ret = t->checkboxHeight;
- return ret;
-}
-
-static void redrawAll(struct table *t)
-{
- if (InvalidateRect(t->hwnd, NULL, TRUE) == 0)
- abort();
- if (UpdateWindow(t->hwnd) == 0)
- abort();
-}
-
-static RECT realClientRect(struct table *t)
-{
- RECT r;
-
- if (GetClientRect(t->hwnd, &r) == 0)
- abort();
- r.top += t->headerHeight;
- return r;
-}
-
-static void repositionHeader(struct table *t)
-{
- RECT r;
- HDLAYOUT headerlayout;
- WINDOWPOS headerpos;
-
- if (GetClientRect(t->hwnd, &r) == 0) // use the whole client rect
- abort();
- // grow the rectangle to the left to fake scrolling
- r.left -= t->hpos;
- headerlayout.prc = &r;
- headerlayout.pwpos = &headerpos;
- if (SendMessageW(t->header, HDM_LAYOUT, 0, (LPARAM) (&headerlayout)) == FALSE)
- abort();
- if (SetWindowPos(t->header, headerpos.hwndInsertAfter, headerpos.x, headerpos.y, headerpos.cx, headerpos.cy, headerpos.flags | SWP_SHOWWINDOW) == 0)
- abort();
- t->headerHeight = headerpos.cy;
-}
-
-// this counts partially visible rows
-// for all fully visible rows use t->pagesize
-// cliprect and rowHeight must be specified here to avoid recomputing things multiple times
-static intptr_t lastVisible(struct table *t, RECT cliprect, LONG rowHeight)
-{
- intptr_t last;
-
- last = ((cliprect.bottom + rowHeight - 1) / rowHeight) + t->firstVisible;
- if (last >= t->count)
- last = t->count;
- return last;
-}
-
-static void redrawRow(struct table *t, intptr_t row)
-{
- RECT r;
- intptr_t height;
-
- r = realClientRect(t);
- height = rowHeight(t);
- if (row < t->firstVisible || row > lastVisible(t, r, height)) // not visible; don't bother
- return;
- r.top = (row - t->firstVisible) * height + t->headerHeight;
- r.bottom = r.top + height;
- // keep the width and height the same; it spans the client area anyway
- if (InvalidateRect(t->hwnd, &r, TRUE) == 0)
- abort();
- if (UpdateWindow(t->hwnd) == 0)
- abort();
-}
-
-static intptr_t hitTestColumn(struct table *t, int x)
-{
- HDITEMW item;
- intptr_t i;
-
- // TODO count dividers
- for (i = 0; i < t->nColumns; i++) {
- ZeroMemory(&item, sizeof (HDITEMW));
- item.mask = HDI_WIDTH;
- if (SendMessageW(t->header, HDM_GETITEM, (WPARAM) i, (LPARAM) (&item)) == FALSE)
- abort();
- if (x < item.cxy)
- return i;
- x -= item.cxy; // not yet
- }
- // no column
- return -1;
-}
-
-static void lParamToRowColumn(struct table *t, LPARAM lParam, intptr_t *row, intptr_t *column)
-{
- int x, y;
- LONG h;
-
- x = GET_X_LPARAM(lParam);
- y = GET_Y_LPARAM(lParam);
- h = rowHeight(t);
- y += t->firstVisible * h;
- y -= t->headerHeight;
- y /= h;
- if (row != NULL) {
- *row = y;
- if (*row >= t->count)
- *row = -1;
- }
- if (column != NULL)
- *column = hitTestColumn(t, x);
-}
-
-static void addColumn(struct table *t, WPARAM wParam, LPARAM lParam)
-{
- HDITEMW item;
-
- if (((int) wParam) >= nTableColumnTypes)
- abort();
-
- t->nColumns++;
- t->columnTypes = (int *) realloc(t->columnTypes, t->nColumns * sizeof (int));
- if (t->columnTypes == NULL)
- abort();
- t->columnTypes[t->nColumns - 1] = (int) wParam;
-
- ZeroMemory(&item, sizeof (HDITEMW));
- item.mask = HDI_WIDTH | HDI_TEXT | HDI_FORMAT;
- item.cxy = 200; // TODO
- item.pszText = (WCHAR *) lParam;
- item.fmt = HDF_LEFT | HDF_STRING;
- if (SendMessage(t->header, HDM_INSERTITEM, (WPARAM) (t->nColumns - 1), (LPARAM) (&item)) == (LRESULT) (-1))
- abort();
- // TODO resize(t)?
- redrawAll(t);
-}
-
-static void hscrollto(struct table *t, intptr_t newpos)
-{
- SCROLLINFO si;
- RECT scrollArea;
-
- if (newpos < 0)
- newpos = 0;
- if (newpos > (t->width - t->hpagesize))
- newpos = (t->width - t->hpagesize);
-
- scrollArea = realClientRect(t);
-
- // negative because ScrollWindowEx() is "backwards"
- if (ScrollWindowEx(t->hwnd, -(newpos - t->hpos), 0,
- &scrollArea, &scrollArea, NULL, NULL,
- SW_ERASE | SW_INVALIDATE) == ERROR)
- abort();
- t->hpos = newpos;
- // TODO text in header controls doesn't redraw?
-
- // TODO put this in a separate function? same for vscroll?
- ZeroMemory(&si, sizeof (SCROLLINFO));
- si.cbSize = sizeof (SCROLLINFO);
- si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
- si.nPage = t->hpagesize;
- si.nMin = 0;
- si.nMax = t->width - 1; // nMax is inclusive
- si.nPos = t->hpos;
- SetScrollInfo(t->hwnd, SB_HORZ, &si, TRUE);
-
- // and finally reposition the header
- repositionHeader(t);
-}
-
-static void hscrollby(struct table *t, intptr_t n)
-{
- hscrollto(t, t->hpos + n);
-}
-
-// unfortunately horizontal wheel scrolling was only added in Vista
-
-static void hscroll(struct table *t, WPARAM wParam)
-{
- SCROLLINFO si;
- intptr_t newpos;
-
- ZeroMemory(&si, sizeof (SCROLLINFO));
- si.cbSize = sizeof (SCROLLINFO);
- si.fMask = SIF_POS | SIF_TRACKPOS;
- if (GetScrollInfo(t->hwnd, SB_HORZ, &si) == 0)
- abort();
-
- newpos = t->hpos;
- switch (LOWORD(wParam)) {
- case SB_LEFT:
- newpos = 0;
- break;
- case SB_RIGHT:
- newpos = t->width - t->hpagesize;
- break;
- case SB_LINELEFT:
- newpos--;
- break;
- case SB_LINERIGHT:
- newpos++;
- break;
- case SB_PAGELEFT:
- newpos -= t->hpagesize;
- break;
- case SB_PAGERIGHT:
- newpos += t->hpagesize;
- break;
- case SB_THUMBPOSITION:
- newpos = (intptr_t) (si.nPos);
- break;
- case SB_THUMBTRACK:
- newpos = (intptr_t) (si.nTrackPos);
- }
-
- hscrollto(t, newpos);
-}
-
-static void recomputeHScroll(struct table *t)
-{
- HDITEMW item;
- intptr_t i;
- int width = 0;
- RECT r;
- SCROLLINFO si;
-
- // TODO count dividers
- for (i = 0; i < t->nColumns; i++) {
- ZeroMemory(&item, sizeof (HDITEMW));
- item.mask = HDI_WIDTH;
- if (SendMessageW(t->header, HDM_GETITEM, (WPARAM) i, (LPARAM) (&item)) == FALSE)
- abort();
- width += item.cxy;
- }
- t->width = (intptr_t) width;
-
- if (GetClientRect(t->hwnd, &r) == 0)
- abort();
- t->hpagesize = r.right - r.left;
-
- ZeroMemory(&si, sizeof (SCROLLINFO));
- si.cbSize = sizeof (SCROLLINFO);
- si.fMask = SIF_PAGE | SIF_RANGE;
- si.nPage = t->hpagesize;
- si.nMin = 0;
- si.nMax = t->width - 1; // - 1 because endpoints inclusive
- SetScrollInfo(t->hwnd, SB_HORZ, &si, TRUE);
-}
-
-static void vscrollto(struct table *t, intptr_t newpos)
-{
- SCROLLINFO si;
- RECT scrollArea;
-
- if (newpos < 0)
- newpos = 0;
- if (newpos > (t->count - t->pagesize))
- newpos = (t->count - t->pagesize);
-
- scrollArea = realClientRect(t);
-
- // negative because ScrollWindowEx() is "backwards"
- if (ScrollWindowEx(t->hwnd, 0, (-(newpos - t->firstVisible)) * rowHeight(t),
- &scrollArea, &scrollArea, NULL, NULL,
- SW_ERASE | SW_INVALIDATE) == ERROR)
- abort();
- t->firstVisible = newpos;
-
- ZeroMemory(&si, sizeof (SCROLLINFO));
- si.cbSize = sizeof (SCROLLINFO);
- si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
- si.nPage = t->pagesize;
- si.nMin = 0;
- si.nMax = t->count - 1; // nMax is inclusive
- si.nPos = t->firstVisible;
- SetScrollInfo(t->hwnd, SB_VERT, &si, TRUE);
-}
-
-static void vscrollby(struct table *t, intptr_t n)
-{
- vscrollto(t, t->firstVisible + n);
-}
-
-static void wheelscroll(struct table *t, WPARAM wParam)
-{
- int delta;
- int lines;
- UINT scrollAmount;
-
- delta = GET_WHEEL_DELTA_WPARAM(wParam);
- if (SystemParametersInfoW(SPI_GETWHEELSCROLLLINES, 0, &scrollAmount, 0) == 0)
- abort();
- if (scrollAmount == WHEEL_PAGESCROLL)
- scrollAmount = t->pagesize;
- if (scrollAmount == 0) // no mouse wheel scrolling (or t->pagesize == 0)
- return;
- // the rest of this is basically http://blogs.msdn.com/b/oldnewthing/archive/2003/08/07/54615.aspx and http://blogs.msdn.com/b/oldnewthing/archive/2003/08/11/54624.aspx
- // see those pages for information on subtleties
- delta += t->wheelCarry;
- lines = delta * ((int) scrollAmount) / WHEEL_DELTA;
- t->wheelCarry = delta - lines * WHEEL_DELTA / ((int) scrollAmount);
- vscrollby(t, -lines);
-}
-
-static void vscroll(struct table *t, WPARAM wParam)
-{
- SCROLLINFO si;
- intptr_t newpos;
-
- ZeroMemory(&si, sizeof (SCROLLINFO));
- si.cbSize = sizeof (SCROLLINFO);
- si.fMask = SIF_POS | SIF_TRACKPOS;
- if (GetScrollInfo(t->hwnd, SB_VERT, &si) == 0)
- abort();
-
- newpos = t->firstVisible;
- switch (LOWORD(wParam)) {
- case SB_TOP:
- newpos = 0;
- break;
- case SB_BOTTOM:
- newpos = t->count - t->pagesize;
- break;
- case SB_LINEUP:
- newpos--;
- break;
- case SB_LINEDOWN:
- newpos++;
- break;
- case SB_PAGEUP:
- newpos -= t->pagesize;
- break;
- case SB_PAGEDOWN:
- newpos += t->pagesize;
- break;
- case SB_THUMBPOSITION:
- newpos = (intptr_t) (si.nPos);
- break;
- case SB_THUMBTRACK:
- newpos = (intptr_t) (si.nTrackPos);
- }
-
- vscrollto(t, newpos);
-}
+#include "util.h"
+#include "api.h"
+#include "hscroll.h"
+#include "vscroll.h"
static void finishSelect(struct table *t, intptr_t prev)
{