From 2013a3a753c6f6ffd1d33cd3862a41f17763ada4 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Fri, 12 Dec 2014 14:53:58 -0500 Subject: [PATCH] Isolated the scrolling code to avoid code duplication in something so sensitive. --- wintable/new/hscroll.h | 100 +++++++++----------------------------- wintable/new/main.c | 1 + wintable/new/scroll.h | 106 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 77 deletions(-) create mode 100644 wintable/new/scroll.h diff --git a/wintable/new/hscroll.h b/wintable/new/hscroll.h index 7c08656..a2534b5 100644 --- a/wintable/new/hscroll.h +++ b/wintable/new/hscroll.h @@ -3,93 +3,41 @@ // forward declaration needed here static void repositionHeader(struct table *); +static struct scrollParams hscrollParams(struct table *t) +{ + struct scrollParams p; + + ZeroMemory(&p, sizeof (struct scrollParams)); + p.pos = &(t->hscrollpos); + p.pagesize = t->hpagesize; + p.length = t->width; + p.scale = 1; + p.post = repositionHeader; + return p; +} + static void hscrollto(struct table *t, intptr_t pos) { - RECT scrollArea; - SCROLLINFO si; + struct scrollParams p; - 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) -;// TODO failure case ignored for now; see https://bugs.winehq.org/show_bug.cgi?id=37706 -// 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; - 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); + p = hscrollParams(t); + scrollto(t, SB_HORZ, &p, pos); } static void hscrollby(struct table *t, intptr_t delta) { - hscrollto(t, t->hscrollpos + delta); + struct scrollParams p; + + p = hscrollParams(t); + scrollby(t, SB_HORZ, &p, delta); } static void hscroll(struct table *t, WPARAM wParam, LPARAM lParam) { - intptr_t pos; - SCROLLINFO si; + struct scrollParams p; - 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); + p = hscrollParams(t); + scroll(t, SB_HORZ, &p, wParam, lParam); } // TODO find out if we can indicriminately check for WM_WHEELHSCROLL @@ -101,5 +49,3 @@ HANDLER(hscrollHandler) *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 9fd705e..509fff0 100644 --- a/wintable/new/main.c +++ b/wintable/new/main.c @@ -66,6 +66,7 @@ struct table { #include "util.h" #include "coord.h" #include "events.h" +#include "scroll.h" #include "hscroll.h" #include "header.h" #include "children.h" diff --git a/wintable/new/scroll.h b/wintable/new/scroll.h new file mode 100644 index 0000000..81b49c5 --- /dev/null +++ b/wintable/new/scroll.h @@ -0,0 +1,106 @@ +// 9 december 2014 + +struct scrollParams { + intptr_t *pos; + intptr_t pagesize; + intptr_t length; + intptr_t scale; + void (*post)(struct table *); +}; + +static void scrollto(struct table *t, int which, struct scrollParams *p, intptr_t pos) +{ + RECT scrollArea; + SCROLLINFO si; + intptr_t xamount, yamount; + + if (pos < 0) + pos = 0; + if (pos > p->length - p->pagesize) + pos = p->length - p->pagesize; + + // we don't want to scroll the header + if (GetClientRect(t->hwnd, &scrollArea) == 0) + panic("error getting Table client rect for scrollto()"); + scrollArea.top += t->headerHeight; + + // negative because ScrollWindowEx() is "backwards" + xamount = -(pos - *(p->pos)) * p->scale; + yamount = 0; + if (which == SB_VERT) { + yamount = xamount; + xamount = 0; + } + + if (ScrollWindowEx(t->hwnd, xamount, yamount, + &scrollArea, &scrollArea, NULL, NULL, + SW_ERASE | SW_INVALIDATE) == ERROR) +;// TODO failure case ignored for now; see https://bugs.winehq.org/show_bug.cgi?id=37706 +// panic("error scrolling Table"); + // TODO call UpdateWindow()? + + *(p->pos) = pos; + + // now commit our new scrollbar setup... + ZeroMemory(&si, sizeof (SCROLLINFO)); + si.cbSize = sizeof (SCROLLINFO); + si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE; + si.nPage = p->pagesize; + si.nMin = 0; + si.nMax = p->length - 1; // endpoint inclusive + si.nPos = *(p->pos); + SetScrollInfo(t->hwnd, which, &si, TRUE); + + if (p->post != NULL) + (*(p->post))(t); +} + +static void scrollby(struct table *t, int which, struct scrollParams *p, intptr_t delta) +{ + scrollto(t, which, p, *(p->pos) + delta); +} + +static void scroll(struct table *t, int which, struct scrollParams *p, WPARAM wParam, LPARAM lParam) +{ + intptr_t pos; + SCROLLINFO si; + + pos = *(p->pos); + switch (LOWORD(wParam)) { + case SB_LEFT: // also SB_TOP + pos = 0; + break; + case SB_RIGHT: // also SB_BOTTOM + pos = p->length - p->pagesize; + break; + case SB_LINELEFT: // also SB_LINEUP + pos--; + break; + case SB_LINERIGHT: // also SB_LINEDOWN + pos++; + break; + case SB_PAGELEFT: // also SB_PAGEUP + pos -= p->pagesize; + break; + case SB_PAGERIGHT: // also SB_PAGEDOWN + pos += p->pagesize; + break; + case SB_THUMBPOSITION: + ZeroMemory(&si, sizeof (SCROLLINFO)); + si.cbSize = sizeof (SCROLLINFO); + si.fMask = SIF_POS; + if (GetScrollInfo(t->hwnd, which, &si) == 0) + panic("error getting thumb position for scroll() 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, which, &si) == 0) + panic("error getting thumb track position for scroll() in Table"); + pos = si.nTrackPos; + break; + } + scrollto(t, which, p, pos); +}