summaryrefslogtreecommitdiff
path: root/wintable/hscroll.h
blob: 6c700a740db17555acaf7367901ad88e53f99335 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// 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);
}