Release 0.4.7
[wine/multimedia.git] / controls / scroll.c
blob83816f5b879fc44ff6111041d2155d7d3dc4d106
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 = ScrollBarGetStorageHeader(hwnd);
90 DestroyWindow(lphs->hWndUp);
91 DestroyWindow(lphs->hWndDown);
92 free(lphs);
93 printf("ScrollBar WM_DESTROY !\n");
94 return 0;
96 case WM_COMMAND:
97 #ifdef DEBUG_SCROLL
98 printf("ScrollBar WM_COMMAND wParam=%X lParam=%lX !\n", wParam, lParam);
99 #endif
100 lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr);
101 if (HIWORD(lParam) != BN_CLICKED) return 0;
102 if (LOWORD(lParam) == lphs->hWndUp)
103 SendMessage(wndPtr->hwndParent, lphs->Direction,
104 SB_LINEUP, MAKELONG(0, hwnd));
105 if (LOWORD(lParam) == lphs->hWndDown)
106 SendMessage(wndPtr->hwndParent, lphs->Direction,
107 SB_LINEDOWN, MAKELONG(0, hwnd));
108 return 0;
110 case WM_LBUTTONDOWN:
111 lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr);
112 GetClientRect(hwnd, &rect);
113 if (lphs->Direction == WM_VSCROLL) {
114 y = HIWORD(lParam);
115 #ifdef DEBUG_SCROLL
116 printf("WM_LBUTTONDOWN y=%d cur+right=%d %d\n",
117 y, lphs->CurPix + rect.right, lphs->CurPix + (rect.right << 1));
118 #endif
119 if (y < (lphs->CurPix + rect.right))
120 SendMessage(wndPtr->hwndParent, lphs->Direction,
121 SB_PAGEUP, MAKELONG(0, hwnd));
122 if (y > (lphs->CurPix + (rect.right << 1)))
123 SendMessage(wndPtr->hwndParent, lphs->Direction,
124 SB_PAGEDOWN, MAKELONG(0, hwnd));
125 if ((y > (lphs->CurPix + rect.right)) &&
126 (y < (lphs->CurPix + (rect.right << 1)))) {
127 lphs->ThumbActive = TRUE;
128 #ifdef DEBUG_SCROLL
129 printf("THUMB DOWN !\n");
130 #endif
133 else {
134 x = LOWORD(lParam);
135 #ifdef DEBUG_SCROLL
136 printf("WM_LBUTTONDOWN x=%d Cur+bottom=%d %d\n",
137 x, lphs->CurPix + rect.bottom, lphs->CurPix + (rect.bottom << 1));
138 #endif
139 if (x < (lphs->CurPix + rect.bottom))
140 SendMessage(wndPtr->hwndParent, lphs->Direction,
141 SB_PAGEUP, MAKELONG(0, hwnd));
142 if (x > (lphs->CurPix + (rect.bottom << 1)))
143 SendMessage(wndPtr->hwndParent, lphs->Direction,
144 SB_PAGEDOWN, MAKELONG(0, hwnd));
145 if ((x > (lphs->CurPix + rect.bottom)) &&
146 (x < (lphs->CurPix + (rect.bottom << 1)))) {
147 lphs->ThumbActive = TRUE;
148 #ifdef DEBUG_SCROLL
149 printf("THUMB DOWN !\n");
150 #endif
153 break;
154 case WM_LBUTTONUP:
155 lphs->ThumbActive = FALSE;
156 break;
158 case WM_KEYDOWN:
159 printf("ScrollBar WM_KEYDOWN wParam %X!\n", wParam);
160 break;
161 case WM_PAINT:
162 StdDrawScrollBar(hwnd);
163 break;
164 case WM_MOUSEMOVE:
165 if ((wParam & MK_LBUTTON) != 0) {
166 lphs = ScrollBarGetWindowAndStorage(hwnd, &wndPtr);
167 if (lphs->ThumbActive == 0) break;
168 GetClientRect(hwnd, &rect);
169 if (lphs->Direction == WM_VSCROLL)
170 y = HIWORD(lParam) - rect.right - (rect.right >> 1);
171 else
172 y = LOWORD(lParam) - rect.bottom - (rect.bottom >> 1);
173 x = (y * (lphs->MaxVal - lphs->MinVal) /
174 lphs->MaxPix) + lphs->MinVal;
175 #ifdef DEBUG_SCROLL
176 printf("WM_MOUSEMOVE val=%d pix=%d\n", x, y);
177 #endif
178 SendMessage(wndPtr->hwndParent, lphs->Direction,
179 SB_THUMBTRACK, MAKELONG(x, hwnd));
181 break;
182 default:
183 return DefWindowProc( hwnd, message, wParam, lParam );
185 return(0);
190 LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hwnd, WND **wndPtr)
192 WND *Ptr;
193 LPHEADSCROLL lphs;
194 *(wndPtr) = Ptr = WIN_FindWndPtr(hwnd);
195 lphs = *((LPHEADSCROLL *)&Ptr->wExtra[1]);
196 return lphs;
200 LPHEADSCROLL ScrollBarGetStorageHeader(HWND hwnd)
202 WND *wndPtr;
203 LPHEADSCROLL lphs;
204 wndPtr = WIN_FindWndPtr(hwnd);
205 lphs = *((LPHEADSCROLL *)&wndPtr->wExtra[1]);
206 return lphs;
210 void StdDrawScrollBar(HWND hwnd)
212 LPHEADSCROLL lphs;
213 PAINTSTRUCT ps;
214 HBRUSH hBrush;
215 HDC hdc;
216 RECT rect;
217 UINT i, w, h, siz;
218 char C[128];
219 hdc = BeginPaint( hwnd, &ps );
220 hBrush = SendMessage(GetParent(hwnd), WM_CTLCOLOR, (WORD)hdc,
221 MAKELONG(hwnd, CTLCOLOR_SCROLLBAR));
222 if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(LTGRAY_BRUSH);
223 lphs = ScrollBarGetStorageHeader(hwnd);
224 if (lphs == NULL) goto EndOfPaint;
225 GetClientRect(hwnd, &rect);
226 w = rect.right - rect.left;
227 h = rect.bottom - rect.top;
228 if (lphs->Direction == WM_VSCROLL) {
229 rect.top += w;
230 rect.bottom -= w;
232 else {
233 rect.left += h;
234 rect.right -= h;
236 FillRect(hdc, &rect, hBrush);
237 if (lphs->Direction == WM_VSCROLL)
238 SetRect(&rect, 0, lphs->CurPix + w,
239 w, lphs->CurPix + (w << 1));
240 else
241 SetRect(&rect, lphs->CurPix + h,
242 0, lphs->CurPix + (h << 1), h);
243 FrameRect(hdc, &rect, GetStockObject(BLACK_BRUSH));
244 InflateRect(&rect, -1, -1);
245 FillRect(hdc, &rect, GetStockObject(LTGRAY_BRUSH));
246 DrawReliefRect(hdc, rect, 2, 0);
247 InflateRect(&rect, -3, -3);
248 DrawReliefRect(hdc, rect, 1, 1);
249 EndOfPaint:
250 EndPaint( hwnd, &ps );
251 InvalidateRect(lphs->hWndUp, NULL, TRUE);
252 UpdateWindow(lphs->hWndUp);
253 InvalidateRect(lphs->hWndDown, NULL, TRUE);
254 UpdateWindow(lphs->hWndDown);
259 int CreateScrollBarStruct(HWND hwnd)
261 RECT rect;
262 int width, height;
263 WND *wndPtr;
264 LPHEADSCROLL lphs;
265 wndPtr = WIN_FindWndPtr(hwnd);
266 lphs = (LPHEADSCROLL)malloc(sizeof(HEADSCROLL));
267 *((LPHEADSCROLL *)&wndPtr->wExtra[1]) = lphs;
268 lphs->ThumbActive;
269 lphs->MinVal = 0;
270 lphs->MaxVal = 100;
271 lphs->CurVal = 0;
272 lphs->CurPix = 0;
273 width = wndPtr->rectClient.right - wndPtr->rectClient.left;
274 height = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
275 lphs = ScrollBarGetStorageHeader(hwnd);
276 if (lphs == NULL) return 0;
277 if (width <= height)
279 lphs->MaxPix = height - 3 * width;
280 lphs->Direction = WM_VSCROLL;
281 lphs->hWndUp = CreateWindow("BUTTON", "",
282 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
283 0, 0, width, width, hwnd, 1, wndPtr->hInstance, 0L);
284 lphs->hWndDown = CreateWindow("BUTTON", "",
285 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
286 0, height - width, width, width, hwnd, 2,
287 wndPtr->hInstance, 0L);
289 else
291 lphs->MaxPix = width - 3 * height;
292 lphs->Direction = WM_HSCROLL;
293 lphs->hWndUp = CreateWindow("BUTTON", "",
294 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
295 0, 0, height, height, hwnd, 0, wndPtr->hInstance, 0L);
296 lphs->hWndDown = CreateWindow("BUTTON", "",
297 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
298 width - height, 0, height, height, hwnd, 0,
299 wndPtr->hInstance, 0L);
301 if (lphs->MaxPix < 1) lphs->MaxPix = 1;
302 return TRUE;
307 int GetScrollPos(HWND hwnd, int nBar)
309 LPHEADSCROLL lphs;
310 lphs = ScrollBarGetStorageHeader(hwnd);
311 if (lphs == NULL) return;
312 return lphs->CurVal;
317 void GetScrollRange(HWND hwnd, int nBar, LPINT lpMin, LPINT lpMax)
319 LPHEADSCROLL lphs;
320 lphs = ScrollBarGetStorageHeader(hwnd);
321 if (lphs == NULL) return;
322 *lpMin = lphs->MinVal;
323 *lpMax = lphs->MaxVal;
328 int SetScrollPos(HWND hwnd, int nBar, int nPos, BOOL bRedraw)
330 int nRet;
331 LPHEADSCROLL lphs;
332 lphs = ScrollBarGetStorageHeader(hwnd);
333 if (lphs == NULL) return;
334 nRet = lphs->CurVal;
335 lphs->CurVal = (short)nPos;
336 if (lphs->MaxVal != lphs->MinVal)
337 lphs->CurPix = lphs->MaxPix * (abs((short)nPos) - abs(lphs->MinVal)) /
338 (abs(lphs->MaxVal) - abs(lphs->MinVal));
339 if (lphs->CurPix > lphs->MaxPix) lphs->CurPix = lphs->MaxPix;
340 #ifdef DEBUG_SCROLL
341 printf("SetScrollPos val=%d pixval=%d pixmax%d\n",
342 (short)nPos, lphs->CurPix, lphs->MaxPix);
343 printf("SetScrollPos min=%d max=%d\n",
344 lphs->MinVal, lphs->MaxVal);
345 #endif
346 if (bRedraw) {
347 InvalidateRect(hwnd, NULL, TRUE);
348 UpdateWindow(hwnd);
350 return nRet;
355 void SetScrollRange(HWND hwnd, int nBar, int MinPos, int MaxPos, BOOL bRedraw)
357 LPHEADSCROLL lphs;
358 lphs = ScrollBarGetStorageHeader(hwnd);
359 if (lphs == NULL) return;
360 lphs->MinVal = (short)MinPos;
361 lphs->MaxVal = (short)MaxPos;
362 if (lphs->MaxVal != lphs->MinVal)
363 lphs->CurPix = abs(lphs->MaxVal) *
364 (abs(lphs->CurVal) - abs(lphs->MinVal)) /
365 (abs(lphs->MaxVal) - abs(lphs->MinVal));
366 if (lphs->CurPix > lphs->MaxPix) lphs->CurPix = lphs->MaxPix;
367 #ifdef DEBUG_SCROLL
368 printf("SetScrollRange min=%d max=%d\n", lphs->MinVal, lphs->MaxVal);
369 #endif
370 if (bRedraw) {
371 InvalidateRect(hwnd, NULL, TRUE);
372 UpdateWindow(hwnd);