Release 0.4.10
[wine/hacks.git] / controls / scroll.c
blobfd8e45a24eeffce3c44fe378d7f72f2d1d30bd49
1 /*
2 * Interface code to SCROLLBAR widget
4 * Copyright Martin Ayotte, 1993
6 */
8 /*
9 #define DEBUG_SCROLL
12 static char Copyright[] = "Copyright Martin Ayotte, 1993";
14 #include <X11/Intrinsic.h>
15 #include <X11/StringDefs.h>
16 #include "windows.h"
17 #include "scroll.h"
18 #include "heap.h"
19 #include "win.h"
20 #include "dirent.h"
21 #include <sys/stat.h>
23 LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hwnd, WND **wndPtr);
24 LPHEADSCROLL ScrollBarGetStorageHeader(HWND hwnd);
25 void StdDrawScrollBar(HWND hwnd);
26 int CreateScrollBarStruct(HWND hwnd);
29 void SCROLLBAR_CreateScrollBar(LPSTR className, LPSTR scrollLabel, HWND hwnd)
31 WND *wndPtr = WIN_FindWndPtr(hwnd);
32 WND *parentPtr = WIN_FindWndPtr(wndPtr->hwndParent);
33 DWORD style;
34 char widgetName[15];
36 #ifdef DEBUG_SCROLLBAR
37 printf("scroll: label = %s, x = %d, y = %d\n", scrollLabel,
38 wndPtr->rectClient.left, wndPtr->rectClient.top);
39 printf(" width = %d, height = %d\n",
40 wndPtr->rectClient.right - wndPtr->rectClient.left,
41 wndPtr->rectClient.bottom - wndPtr->rectClient.top);
42 #endif
44 if (!wndPtr)
45 return;
47 style = wndPtr->dwStyle & 0x0000FFFF;
49 if ((style & SBS_NOTIFY) == SBS_NOTIFY)
50 */
51 sprintf(widgetName, "%s%d", className, wndPtr->wIDmenu);
52 wndPtr->winWidget = XtVaCreateManagedWidget(widgetName,
53 compositeWidgetClass,
54 parentPtr->winWidget,
55 XtNx, wndPtr->rectClient.left,
56 XtNy, wndPtr->rectClient.top,
57 XtNwidth, wndPtr->rectClient.right -
58 wndPtr->rectClient.left,
59 XtNheight, wndPtr->rectClient.bottom -
60 wndPtr->rectClient.top,
61 NULL );
62 GlobalUnlock(hwnd);
63 GlobalUnlock(wndPtr->hwndParent);
68 /***********************************************************************
69 * WIDGETS_ScrollBarWndProc
71 LONG SCROLLBAR_ScrollBarWndProc( HWND hwnd, WORD message,
72 WORD wParam, LONG lParam )
74 WORD wRet;
75 short x, y;
76 WND *wndPtr;
77 LPHEADSCROLL lphs;
78 RECT rect;
79 static RECT rectsel;
80 switch(message)
82 case WM_CREATE:
83 CreateScrollBarStruct(hwnd);
84 #ifdef DEBUG_SCROLL
85 printf("ScrollBar Creation up=%X down=%X!\n", lphs->hWndUp, lphs->hWndDown);
86 #endif
87 return 0;
88 case WM_DESTROY:
89 lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr);
90 if (lphs == 0) return 0;
91 #ifdef DEBUG_SCROLL
92 printf("ScrollBar WM_DESTROY %lX !\n", lphs);
93 #endif
94 DestroyWindow(lphs->hWndUp);
95 DestroyWindow(lphs->hWndDown);
96 free(lphs);
97 *((LPHEADSCROLL *)&wndPtr->wExtra[1]) = 0;
98 return 0;
100 case WM_COMMAND:
101 #ifdef DEBUG_SCROLL
102 printf("ScrollBar WM_COMMAND wParam=%X lParam=%lX !\n", wParam, lParam);
103 #endif
104 lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr);
105 if (HIWORD(lParam) != BN_CLICKED) return 0;
106 if (LOWORD(lParam) == lphs->hWndUp)
107 SendMessage(wndPtr->hwndParent, lphs->Direction,
108 SB_LINEUP, MAKELONG(0, hwnd));
109 if (LOWORD(lParam) == lphs->hWndDown)
110 SendMessage(wndPtr->hwndParent, lphs->Direction,
111 SB_LINEDOWN, MAKELONG(0, hwnd));
113 SetFocus(hwnd);
115 return 0;
117 case WM_LBUTTONDOWN:
118 lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr);
120 SetFocus(hwnd);
122 SetCapture(hwnd);
123 GetClientRect(hwnd, &rect);
124 if (lphs->Direction == WM_VSCROLL) {
125 y = HIWORD(lParam);
126 #ifdef DEBUG_SCROLL
127 printf("WM_LBUTTONDOWN y=%d cur+right=%d %d\n",
128 y, lphs->CurPix + rect.right, lphs->CurPix + (rect.right << 1));
129 #endif
130 if (y < (lphs->CurPix + rect.right))
131 SendMessage(wndPtr->hwndParent, lphs->Direction,
132 SB_PAGEUP, MAKELONG(0, hwnd));
133 if (y > (lphs->CurPix + (rect.right << 1)))
134 SendMessage(wndPtr->hwndParent, lphs->Direction,
135 SB_PAGEDOWN, MAKELONG(0, hwnd));
136 if ((y > (lphs->CurPix + rect.right)) &&
137 (y < (lphs->CurPix + (rect.right << 1)))) {
138 lphs->ThumbActive = TRUE;
139 #ifdef DEBUG_SCROLL
140 printf("THUMB DOWN !\n");
141 #endif
144 else {
145 x = LOWORD(lParam);
146 #ifdef DEBUG_SCROLL
147 printf("WM_LBUTTONDOWN x=%d Cur+bottom=%d %d\n",
148 x, lphs->CurPix + rect.bottom, lphs->CurPix + (rect.bottom << 1));
149 #endif
150 if (x < (lphs->CurPix + rect.bottom))
151 SendMessage(wndPtr->hwndParent, lphs->Direction,
152 SB_PAGEUP, MAKELONG(0, hwnd));
153 if (x > (lphs->CurPix + (rect.bottom << 1)))
154 SendMessage(wndPtr->hwndParent, lphs->Direction,
155 SB_PAGEDOWN, MAKELONG(0, hwnd));
156 if ((x > (lphs->CurPix + rect.bottom)) &&
157 (x < (lphs->CurPix + (rect.bottom << 1)))) {
158 lphs->ThumbActive = TRUE;
159 #ifdef DEBUG_SCROLL
160 printf("THUMB DOWN !\n");
161 #endif
164 break;
165 case WM_LBUTTONUP:
166 lphs = ScrollBarGetStorageHeader(hwnd);
167 lphs->ThumbActive = FALSE;
168 ReleaseCapture();
169 break;
171 case WM_KEYDOWN:
172 printf("ScrollBar WM_KEYDOWN wParam %X !\n", wParam);
173 break;
174 case WM_PAINT:
175 StdDrawScrollBar(hwnd);
176 break;
177 case WM_MOUSEMOVE:
178 if ((wParam & MK_LBUTTON) != 0) {
179 lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr);
180 if (lphs->ThumbActive == 0) break;
181 GetClientRect(hwnd, &rect);
182 if (lphs->Direction == WM_VSCROLL)
183 y = HIWORD(lParam) - rect.right - (rect.right >> 1);
184 else
185 y = LOWORD(lParam) - rect.bottom - (rect.bottom >> 1);
186 x = (y * (lphs->MaxVal - lphs->MinVal) /
187 lphs->MaxPix) + lphs->MinVal;
188 #ifdef DEBUG_SCROLL
189 printf("WM_MOUSEMOVE val=%d pix=%d\n", x, y);
190 #endif
191 SendMessage(wndPtr->hwndParent, lphs->Direction,
192 SB_THUMBTRACK, MAKELONG(x, hwnd));
194 break;
195 default:
196 return DefWindowProc( hwnd, message, wParam, lParam );
198 return(0);
203 LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hwnd, WND **wndPtr)
205 WND *Ptr;
206 LPHEADSCROLL lphs;
207 *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd);
208 if (Ptr == 0) {
209 printf("Bad Window handle on ScrollBar !\n");
210 return 0;
212 lphs = *((LPHEADSCROLL *)&Ptr->wExtra[1]);
213 return lphs;
217 LPHEADSCROLL ScrollBarGetStorageHeader(HWND hwnd)
219 WND *wndPtr;
220 LPHEADSCROLL lphs;
221 wndPtr = WIN_FindWndPtr(hwnd);
222 if (wndPtr == 0) {
223 printf("Bad Window handle on ScrollBar !\n");
224 return 0;
226 lphs = *((LPHEADSCROLL *)&wndPtr->wExtra[1]);
227 return lphs;
231 void StdDrawScrollBar(HWND hwnd)
233 LPHEADSCROLL lphs;
234 PAINTSTRUCT ps;
235 HBRUSH hBrush;
236 HDC hdc;
237 RECT rect;
238 UINT i, w, h, siz;
239 char C[128];
240 hdc = BeginPaint( hwnd, &ps );
241 if (!IsWindowVisible(hwnd)) {
242 EndPaint( hwnd, &ps );
243 return;
245 hBrush = SendMessage(GetParent(hwnd), WM_CTLCOLOR, (WORD)hdc,
246 MAKELONG(hwnd, CTLCOLOR_SCROLLBAR));
247 if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(LTGRAY_BRUSH);
248 lphs = ScrollBarGetStorageHeader(hwnd);
249 if (lphs == NULL) goto EndOfPaint;
250 GetClientRect(hwnd, &rect);
251 w = rect.right - rect.left;
252 h = rect.bottom - rect.top;
253 if (lphs->Direction == WM_VSCROLL) {
254 rect.top += w;
255 rect.bottom -= w;
257 else {
258 rect.left += h;
259 rect.right -= h;
261 FillRect(hdc, &rect, hBrush);
262 if (lphs->Direction == WM_VSCROLL)
263 SetRect(&rect, 0, lphs->CurPix + w, w, lphs->CurPix + (w << 1));
264 else
265 SetRect(&rect, lphs->CurPix + h, 0, lphs->CurPix + (h << 1), h);
266 FrameRect(hdc, &rect, GetStockObject(BLACK_BRUSH));
267 InflateRect(&rect, -1, -1);
268 FillRect(hdc, &rect, GetStockObject(LTGRAY_BRUSH));
269 DrawReliefRect(hdc, rect, 2, 0);
270 InflateRect(&rect, -3, -3);
271 DrawReliefRect(hdc, rect, 1, 1);
272 if (!lphs->ThumbActive) {
273 InvalidateRect(lphs->hWndUp, NULL, TRUE);
274 UpdateWindow(lphs->hWndUp);
275 InvalidateRect(lphs->hWndDown, NULL, TRUE);
276 UpdateWindow(lphs->hWndDown);
278 EndOfPaint:
279 EndPaint( hwnd, &ps );
284 int CreateScrollBarStruct(HWND hwnd)
286 RECT rect;
287 int width, height;
288 WND *wndPtr;
289 LPHEADSCROLL lphs;
290 wndPtr = WIN_FindWndPtr(hwnd);
291 lphs = (LPHEADSCROLL)malloc(sizeof(HEADSCROLL));
292 if (lphs == 0) {
293 printf("Bad Memory Alloc on ScrollBar !\n");
294 return 0;
297 #ifdef DEBUG_SCROLL
298 printf("CreateScrollBarStruct %lX !\n", lphs);
299 #endif
300 *((LPHEADSCROLL *)&wndPtr->wExtra[1]) = lphs;
301 lphs->ThumbActive = FALSE;
302 lphs->MinVal = 0;
303 lphs->MaxVal = 100;
304 lphs->CurVal = 0;
305 lphs->CurPix = 0;
306 width = wndPtr->rectClient.right - wndPtr->rectClient.left;
307 height = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
308 if (width <= height)
310 lphs->MaxPix = height - 3 * width;
311 lphs->Direction = WM_VSCROLL;
312 lphs->hWndUp = CreateWindow("BUTTON", "",
313 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
314 0, 0, width, width, hwnd, 1, wndPtr->hInstance, 0L);
315 lphs->hWndDown = CreateWindow("BUTTON", "",
316 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
317 0, height - width, width, width, hwnd, 2,
318 wndPtr->hInstance, 0L);
320 else
322 lphs->MaxPix = width - 3 * height;
323 lphs->Direction = WM_HSCROLL;
324 lphs->hWndUp = CreateWindow("BUTTON", "",
325 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
326 0, 0, height, height, hwnd, 0, wndPtr->hInstance, 0L);
327 lphs->hWndDown = CreateWindow("BUTTON", "",
328 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
329 width - height, 0, height, height, hwnd, 0,
330 wndPtr->hInstance, 0L);
332 if (lphs->MaxPix < 1) lphs->MaxPix = 1;
333 return TRUE;
338 int GetScrollPos(HWND hwnd, int nBar)
340 LPHEADSCROLL lphs;
341 lphs = ScrollBarGetStorageHeader(hwnd);
342 if (lphs == NULL) return 0;
343 return lphs->CurVal;
348 void GetScrollRange(HWND hwnd, int nBar, LPINT lpMin, LPINT lpMax)
350 LPHEADSCROLL lphs;
351 lphs = ScrollBarGetStorageHeader(hwnd);
352 if (lphs == NULL) return;
353 *lpMin = lphs->MinVal;
354 *lpMax = lphs->MaxVal;
359 int SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL bRedraw)
361 int nRet;
362 LPHEADSCROLL lphs;
363 lphs = ScrollBarGetStorageHeader(hwnd);
364 if (lphs == NULL) return 0;
365 nRet = lphs->CurVal;
366 lphs->CurVal = (short)nPos;
367 if (lphs->MaxVal != lphs->MinVal)
368 lphs->CurPix = lphs->MaxPix * (abs((short)nPos) - abs(lphs->MinVal)) /
369 (abs(lphs->MaxVal) - abs(lphs->MinVal));
370 if (lphs->CurPix > lphs->MaxPix) lphs->CurPix = lphs->MaxPix;
371 #ifdef DEBUG_SCROLL
372 printf("SetScrollPos val=%d pixval=%d pixmax%d\n",
373 (short)nPos, lphs->CurPix, lphs->MaxPix);
374 printf("SetScrollPos min=%d max=%d\n",
375 lphs->MinVal, lphs->MaxVal);
376 #endif
377 if ((bRedraw) && (IsWindowVisible(hwnd))) {
378 InvalidateRect(hwnd, NULL, TRUE);
379 UpdateWindow(hwnd);
381 return nRet;
386 void SetScrollRange(HWND hwnd, int nBar, int MinPos, int MaxPos, BOOL bRedraw)
388 LPHEADSCROLL lphs;
389 lphs = ScrollBarGetStorageHeader(hwnd);
390 if (lphs == NULL) return;
391 lphs->MinVal = (short)MinPos;
392 lphs->MaxVal = (short)MaxPos;
393 if (lphs->MaxVal != lphs->MinVal)
394 lphs->CurPix = abs(lphs->MaxVal) *
395 (abs(lphs->CurVal) - abs(lphs->MinVal)) /
396 (abs(lphs->MaxVal) - abs(lphs->MinVal));
397 if (lphs->CurPix > lphs->MaxPix) lphs->CurPix = lphs->MaxPix;
398 #ifdef DEBUG_SCROLL
399 printf("SetScrollRange min=%d max=%d\n", lphs->MinVal, lphs->MaxVal);
400 #endif
401 if ((bRedraw) && (IsWindowVisible(hwnd))) {
402 InvalidateRect(hwnd, NULL, TRUE);
403 UpdateWindow(hwnd);