summaryrefslogtreecommitdiff
path: root/wintable/new/hscroll.h
blob: f4efc37594f4be019251a754dcb7238217417346 (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
// 9 december 2014

// forward declaration needed here
static void repositionHeader(struct table *);

static void hscrollto(struct table *t, intptr_t pos)
{
	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)
;// 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;
	// 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)
{
	hscrollto(t, t->hscrollpos + delta);
}

static void hscroll(struct table *t, WPARAM wParam, LPARAM lParam)
{
	intptr_t pos;
	SCROLLINFO si;

	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