From 62a1db47566e1f31a9140fc8e8a3e35733a4e5ad Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Wed, 10 Dec 2014 15:37:52 -0500 Subject: [PATCH] Wrote up the hscroll code. Not sure why it doesn't work yet. Not yet applied to headers or drawing. --- wintable/new/header.h | 4 +- wintable/new/hscroll.h | 109 ++++++++++++++++++++++++++++++++++------- wintable/new/main.c | 3 ++ 3 files changed, 96 insertions(+), 20 deletions(-) diff --git a/wintable/new/header.h b/wintable/new/header.h index b992235..ba2d4d4 100644 --- a/wintable/new/header.h +++ b/wintable/new/header.h @@ -68,8 +68,8 @@ static void updateTableWidth(struct table *t) panic("error getting Table column width for updateTableWidth()"); t->width += item.cxy; } - // TODO replace this with a call to hscrollby(t, 0) - recomputeHScroll(t); + // do a dummy scroll to update the horizontal scrollbar to use the new width + hscrollby(t, 0); } HANDLER(headerNotifyHandler) diff --git a/wintable/new/hscroll.h b/wintable/new/hscroll.h index 84ddc3b..9d644c5 100644 --- a/wintable/new/hscroll.h +++ b/wintable/new/hscroll.h @@ -1,33 +1,106 @@ // 9 december 2014 +// forward declaration needed here +static void repositionHeader(struct table *); + static void hscrollto(struct table *t, intptr_t pos) { - // TODO + RECT scrollArea; + SCROLLINFO si; + + if (pos < 0) + pos = 0; + if (pos > t->width - t->hpagesize) + pos = t->width - t->hpagesize; + + // we don't want to scroll the header + if (GetClientRect(t->hwnd, &scrollArea) == 0) + panic("error getting Table client rect for hscrollto()"); + scrollArea.top += t->headerHeight; + + // negative because ScrollWindowEx() is "backwards" + if (ScrollWindowEx(t->hwnd, -(pos - t->hscrollpos), 0, + &scrollArea, &scrollArea, NULL, NULL, + SW_ERASE | SW_INVALIDATE) == ERROR) + panic("error horizontally scrolling Table"); + // TODO call UpdateWindow()? + + t->hscrollpos = pos; + + // now commit our new scrollbar setup... + ZeroMemory(&si, sizeof (SCROLLINFO)); + si.cbSize = sizeof (SCROLLINFO); + si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE; + // the width of scrollArea is unchanged here; use it + t->hpagesize = scrollArea.right - scrollArea.left; + si.nPage = t->hpagesize; + si.nMin = 0; + si.nMax = t->width - 1; // endpoint inclusive + si.nPos = t->hscrollpos; + SetScrollInfo(t->hwnd, SB_HORZ, &si, TRUE); + + // and finally move the header + repositionHeader(t); } static void hscrollby(struct table *t, intptr_t delta) { - // TODO + hscrollto(t, t->hscrollpos + delta); } static void hscroll(struct table *t, WPARAM wParam, LPARAM lParam) { - // TODO -} - -static void recomputeHScroll(struct table *t) -{ + intptr_t pos; SCROLLINFO si; - RECT r; - if (GetClientRect(t->hwnd, &r) == 0) - panic("error getting Table client rect for recomputeHScroll()"); - ZeroMemory(&si, sizeof (SCROLLINFO)); - si.cbSize = sizeof (SCROLLINFO); - si.fMask = SIF_PAGE | SIF_RANGE; - si.nPage = r.right - r.left; - si.nMin = 0; - si.nMax = t->width - 1; // endpoint inclusive - SetScrollInfo(t->hwnd, SB_HORZ, &si, TRUE); - // TODO what happens if the above call renders the current scroll position moot? + pos = t->hscrollpos; + switch (LOWORD(wParam)) { + case SB_LEFT: + pos = 0; + break; + case SB_RIGHT: + pos = t->width - t->hpagesize; + break; + case SB_LINELEFT: + pos--; + break; + case SB_LINERIGHT: + pos++; + break; + case SB_PAGELEFT: + pos -= t->hpagesize; + break; + case SB_PAGERIGHT: + pos += t->hpagesize; + break; + case SB_THUMBPOSITION: + ZeroMemory(&si, sizeof (SCROLLINFO)); + si.cbSize = sizeof (SCROLLINFO); + si.fMask = SIF_POS; + if (GetScrollInfo(t->hwnd, SB_HORZ, &si) == 0) + panic("error getting thumb position for WM_HSCROLL in Table"); + pos = si.nPos; + break; + case SB_THUMBTRACK: + ZeroMemory(&si, sizeof (SCROLLINFO)); + si.cbSize = sizeof (SCROLLINFO); + si.fMask = SIF_TRACKPOS; + if (GetScrollInfo(t->hwnd, SB_HORZ, &si) == 0) + panic("error getting thumb track position for WM_HSCROLL in Table"); + pos = si.nTrackPos; + break; + } + hscrollto(t, pos); } + +// TODO find out if we can indicriminately check for WM_WHEELHSCROLL +HANDLER(hscrollHandler) +{ + if (uMsg != WM_HSCROLL) + return FALSE; + hscroll(t, wParam, lParam); + *lResult = 0; + return TRUE; +} + +// TODO when we write vscroll.h, see just /what/ is common so we can isolate it diff --git a/wintable/new/main.c b/wintable/new/main.c index 0ad1d30..1a33e41 100644 --- a/wintable/new/main.c +++ b/wintable/new/main.c @@ -54,6 +54,8 @@ struct table { int *columnTypes; intptr_t width; intptr_t headerHeight; + intptr_t hscrollpos; + intptr_t hpagesize; }; #include "util.h" @@ -72,6 +74,7 @@ static const handlerfunc handlers[] = { resizeHandler, drawHandlers, apiHandlers, + hscrollHandler, NULL, };