Initial scrollbar code
[reactos.git] / reactos / subsys / win32k / ntuser / scrollbar.c
1 /* $Id: scrollbar.c,v 1.1 2002/11/24 20:15:37 jfilby Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Scrollbars
6 * FILE: subsys/win32k/ntuser/scrollbar.c
7 * PROGRAMER: Jason Filby (jasonfilby@yahoo.com)
8 * REVISION HISTORY:
9 * 16-11-2002 Jason Filby Created
10 */
11 /* INCLUDES ******************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include <win32k/win32k.h>
15 #include <include/object.h>
16 #include <include/window.h>
17 #include <include/class.h>
18 #include <include/error.h>
19 #include <include/winsta.h>
20 #include <include/winpos.h>
21 #include <include/rect.h>
22
23 //#define NDEBUG
24 #include <debug.h>
25
26 #define SCROLL_MIN_RECT 4 /* Minimum size of the rectangle between the arrows */
27 #define SCROLL_ARROW_THUMB_OVERLAP 0 /* Overlap between arrows and thumb */
28
29 /* FUNCTIONS *****************************************************************/
30
31 /* Ported from WINE20020904 */
32 /* Compute the scroll bar rectangle, in drawing coordinates (i.e. client coords for SB_CTL, window coords for SB_VERT and
33 * SB_HORZ). 'arrowSize' returns the width or height of an arrow (depending on * the orientation of the scrollbar),
34 * 'thumbSize' returns the size of the thumb, and 'thumbPos' returns the position of the thumb relative to the left or to
35 * the top. Return TRUE if the scrollbar is vertical, FALSE if horizontal.
36 */
37 static BOOL
38 SCROLL_GetScrollBarRect (PWINDOW_OBJECT Window, INT nBar, PRECT lprect,
39 PINT arrowSize, PINT thumbSize, PINT thumbPos)
40 {
41 INT pixels;
42 BOOL vertical;
43 RECT ClientRect;
44 ULONG Style;
45 DbgPrint("[SCROLL_GetScrollBarRect]");
46 W32kGetClientRect (Window, &ClientRect);
47 DbgPrint("[WindowRect:%d,%d,%d,%d]\n", Window->WindowRect.left, Window->WindowRect.top, Window->WindowRect.right, Window->WindowRect.bottom);
48 DbgPrint("[ClientRect:%d,%d,%d,%d]\n", ClientRect.left, ClientRect.top, ClientRect.right, ClientRect.bottom);
49
50 switch (nBar)
51 {
52 case SB_HORZ:
53 DbgPrint ("[SCROLL_GetScrollBarRect:SB_HORZ]");
54 lprect->left = ClientRect.left - Window->WindowRect.left;
55 lprect->top = ClientRect.bottom - Window->WindowRect.top;
56 lprect->right = ClientRect.right - Window->WindowRect.left;
57 lprect->bottom = lprect->top + NtUserGetSystemMetrics (SM_CYHSCROLL);
58 if (Window->Style & WS_BORDER)
59 {
60 lprect->left--;
61 lprect->right++;
62 }
63 else if (Window->Style & WS_VSCROLL)
64 lprect->right++;
65 vertical = FALSE;
66 break;
67
68 case SB_VERT:
69 DbgPrint ("[SCROLL_GetScrollBarRect:SB_VERT]\n");
70 /* lprect->left = ClientRect.right - Window->WindowRect.left;
71 lprect->top = ClientRect.top - Window->WindowRect.top;
72 lprect->right = lprect->left + NtUserGetSystemMetrics (SM_CXVSCROLL);
73 lprect->bottom = ClientRect.bottom - WindowRect.top; */
74 lprect->left = Window->WindowRect.left + ClientRect.right;
75 lprect->top = Window->WindowRect.bottom - ClientRect.bottom;
76 lprect->right = lprect->left + NtUserGetSystemMetrics (SM_CXVSCROLL);
77 lprect->bottom = Window->WindowRect.bottom;
78 if (Window->Style & WS_BORDER)
79 {
80 lprect->top--;
81 lprect->bottom++;
82 }
83 else if (Window->Style & WS_HSCROLL)
84 lprect->bottom++;
85 DbgPrint ("[VERTDIMEN:%d,%d,%d,%d]\n", lprect->left, lprect->top,
86 lprect->right, lprect->bottom);
87 DbgPrint ("[Window:%d,%d,%d,%d]\n", Window->WindowRect.left, Window->WindowRect.top,
88 Window->WindowRect.right, Window->WindowRect.bottom);
89 DbgPrint ("[Client:%d,%d,%d,%d]\n", ClientRect.left, ClientRect.top,
90 ClientRect.right, ClientRect.bottom);
91 DbgPrint ("[NtUserGetSystemMetrics(SM_CXVSCROLL):%d]\n",
92 NtUserGetSystemMetrics (SM_CXVSCROLL));
93 vertical = TRUE;
94 break;
95
96 case SB_CTL:
97 DbgPrint ("[SCROLL_GetScrollBarRect:SB_CTL]");
98 W32kGetClientRect (Window, lprect);
99 vertical = ((Window->Style & SBS_VERT) != 0);
100 break;
101
102 default:
103 DbgPrint ("[SCROLL_GetScrollBarRect:FAIL]");
104 W32kReleaseWindowObject(Window);
105 return FALSE;
106 }
107
108 if (vertical)
109 pixels = lprect->bottom - lprect->top;
110 else
111 pixels = lprect->right - lprect->left;
112
113 if (pixels <= 2 * NtUserGetSystemMetrics (SM_CXVSCROLL) + SCROLL_MIN_RECT)
114 {
115 if (pixels > SCROLL_MIN_RECT)
116 *arrowSize = (pixels - SCROLL_MIN_RECT) / 2;
117 else
118 *arrowSize = 0;
119 *thumbPos = *thumbSize = 0;
120 }
121 else
122 {
123 /* PSCROLLBARINFO info;
124
125 NtUserGetScrollBarInfo (hWnd, nBar, info); recursive loop.. since called function calls this function */
126
127 *arrowSize = NtUserGetSystemMetrics (SM_CXVSCROLL);
128 pixels -=
129 (2 * (NtUserGetSystemMetrics (SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP));
130 /* if (info->Page)
131 {
132 thumbSize = MulDiv(pixels,info->Page,(info->MaxVal-info->MinVal+1));
133 if (*thumbSize < SCROLL_MIN_THUMB) *thumbSize = SCROLL_MIN_THUMB;
134 }
135 else *thumbSize = NtUserGetSystemMetrics(SM_CXVSCROLL); */
136 /*
137 if (((pixels -= *thumbSize ) < 0) ||
138 ((info->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH))
139 { */
140 /* Rectangle too small or scrollbar disabled -> no thumb */
141 /* *thumbPos = *thumbSize = 0;
142 }
143 else
144 { */
145 /* INT max = info->MaxVal - max( info->Page-1, 0 );
146 if (info->MinVal >= max)
147 *thumbPos = *arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
148 else
149 *thumbPos = *arrowSize - SCROLL_ARROW_THUMB_OVERLAP
150 + MulDiv(pixels, (info->CurVal-info->MinVal),(max - info->MinVal));
151 } */
152 }
153 W32kReleaseWindowObject(Window);
154
155 return vertical;
156 }
157
158 DWORD
159 STDCALL
160 NtUserGetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
161 {
162 PWINDOW_OBJECT Window = W32kGetWindowObject(hWnd);
163 int thumbSize = 20, arrowSize = 20, thumbPos = 0;
164
165 if (!Window) return FALSE;
166
167 switch(idObject)
168 {
169 case SB_HORZ: psbi = Window->pHScroll; break;
170 case SB_VERT: psbi = Window->pVScroll; break;
171 case SB_CTL: psbi = Window->wExtra; break;
172 default:
173 W32kReleaseWindowObject(Window);
174 return FALSE;
175 }
176
177 if (!psbi) /* Create the info structure if needed */
178 {
179 if ((psbi = ExAllocatePool(NonPagedPool, sizeof(SCROLLBARINFO))))
180 {
181 DbgPrint("Creating PSCROLLBARINFO for %d - psbi: %08x\n", idObject, psbi);
182 SCROLL_GetScrollBarRect (Window, idObject, &(psbi->rcScrollBar), &arrowSize, &thumbSize, &thumbPos);
183 DbgPrint("NtUserGetScrollBarInfo: Creating with rect (%d,%d,%d,%d)\n",
184 psbi->rcScrollBar.left, psbi->rcScrollBar.top, psbi->rcScrollBar.right, psbi->rcScrollBar.bottom);
185
186 if (idObject == SB_HORZ) Window->pHScroll = psbi;
187 else Window->pVScroll = psbi;
188 }
189 /* if (!hUpArrow) SCROLL_LoadBitmaps(); FIXME: This must be moved somewhere in user32 code */
190 }
191 DbgPrint("z1: psbi: %08x\n", psbi);
192 W32kReleaseWindowObject(Window);
193 DbgPrint("z2: psbi: %08x\n", psbi);
194 return TRUE;
195 }
196
197 /* Ported from WINE20020904 */
198 BOOL
199 SCROLL_ShowScrollBar (HWND hwnd, INT nBar, BOOL fShowH, BOOL fShowV)
200 {
201 PWINDOW_OBJECT Window = W32kGetWindowObject(hwnd);
202
203 switch (nBar)
204 {
205 case SB_CTL:
206 NtUserShowWindow (hwnd, fShowH ? SW_SHOW : SW_HIDE);
207 return TRUE;
208
209 case SB_BOTH:
210 case SB_HORZ:
211 if (fShowH)
212 {
213 fShowH = !(Window->Style & WS_HSCROLL);
214 Window->Style |= WS_HSCROLL;
215 }
216 else /* hide it */
217 {
218 fShowH = (Window->Style & WS_HSCROLL);
219 Window->Style &= ~WS_HSCROLL;
220 }
221 if (nBar == SB_HORZ)
222 {
223 fShowV = FALSE;
224 break;
225 }
226 /* fall through */
227
228 case SB_VERT:
229 if (fShowV)
230 {
231 fShowV = !(Window->Style & WS_VSCROLL);
232 Window->Style |= WS_VSCROLL;
233 }
234 else /* hide it */
235 {
236 fShowV = (Window->Style & WS_VSCROLL);
237 Window->Style &= ~WS_VSCROLL;
238 }
239 if (nBar == SB_VERT)
240 fShowH = FALSE;
241 break;
242
243 default:
244 return FALSE; /* Nothing to do! */
245 }
246
247 if (fShowH || fShowV) /* frame has been changed, let the window redraw itself */
248 {
249 NtUserSetWindowPos (hwnd, 0, 0, 0, 0, 0,
250 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
251 return TRUE;
252 }
253 return FALSE; /* no frame changes */
254 }
255
256 DWORD
257 STDCALL
258 NtUserEnableScrollBar(
259 DWORD Unknown0,
260 DWORD Unknown1,
261 DWORD Unknown2)
262 {
263 return 0;
264 }
265
266 DWORD
267 STDCALL
268 NtUserScrollDC(
269 DWORD Unknown0,
270 DWORD Unknown1,
271 DWORD Unknown2,
272 DWORD Unknown3,
273 DWORD Unknown4,
274 DWORD Unknown5,
275 DWORD Unknown6)
276
277 {
278 UNIMPLEMENTED
279
280 return 0;
281 }
282
283 DWORD
284 STDCALL
285 NtUserSetScrollInfo(
286 DWORD Unknown0,
287 DWORD Unknown1,
288 DWORD Unknown2,
289 DWORD Unknown3)
290 {
291 UNIMPLEMENTED
292
293 return 0;
294 }
295
296 DWORD
297 STDCALL
298 NtUserShowScrollBar(HWND hWnd, int wBar, DWORD bShow)
299 {
300 DbgPrint("[NtUserShowScrollBar:%d]", bShow);
301 SCROLL_ShowScrollBar (hWnd, wBar, (wBar == SB_VERT) ? 0 : bShow, (wBar == SB_HORZ) ? 0 : bShow);
302
303 return 0;
304 }
305
306 /* EOF */