andlabs-ui/wintable/hscroll.h

126 lines
2.6 KiB
C

// 29 november 2014
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);
}
HANDLER(hscroll)
{
switch (uMsg) {
case WM_HSCROLL:
hscroll(t, wParam);
*lResult = 0;
return TRUE;
}
return FALSE;
}