summaryrefslogtreecommitdiff
path: root/wintable/scroll.h
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2015-01-06 17:27:41 -0500
committerPietro Gagliardi <[email protected]>2015-01-06 17:27:41 -0500
commit22123fb676d26d309d428a892c453e35e684e367 (patch)
tree9552f1a91a8b8995065e74573e8f59f448f2b08c /wintable/scroll.h
parent720049bfd3c6d205859f3150dee33dee78dc3dc3 (diff)
Merged wintable/new/ into wintable/.
Diffstat (limited to 'wintable/scroll.h')
-rw-r--r--wintable/scroll.h130
1 files changed, 130 insertions, 0 deletions
diff --git a/wintable/scroll.h b/wintable/scroll.h
new file mode 100644
index 0000000..1f333a8
--- /dev/null
+++ b/wintable/scroll.h
@@ -0,0 +1,130 @@
+// 9 december 2014
+
+struct scrollParams {
+ intptr_t *pos;
+ intptr_t pagesize;
+ intptr_t length;
+ intptr_t scale;
+ void (*post)(struct table *);
+ int *wheelCarry;
+};
+
+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);
+}
+
+static void wheelscroll(struct table *t, int which, struct scrollParams *p, WPARAM wParam, LPARAM lParam)
+{
+ int delta;
+ int lines;
+ UINT scrollAmount;
+
+ delta = GET_WHEEL_DELTA_WPARAM(wParam);
+ // TODO make a note of what the appropriate hscroll constant is
+ if (SystemParametersInfoW(SPI_GETWHEELSCROLLLINES, 0, &scrollAmount, 0) == 0)
+ // TODO use scrollAmount == 3 instead?
+ panic("error getting wheel scroll amount in wheelscroll()");
+ if (scrollAmount == WHEEL_PAGESCROLL)
+ scrollAmount = p->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 += *(p->wheelCarry);
+ lines = delta * ((int) scrollAmount) / WHEEL_DELTA;
+ *(p->wheelCarry) = delta - lines * WHEEL_DELTA / ((int) scrollAmount);
+ scrollby(t, which, p, -lines);
+}