Mercurial > projects > dwt-win
comparison dwt/widgets/Scrollable.d @ 213:36f5cb12e1a2
Update to SWT 3.4M7
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 17 May 2008 17:34:28 +0200 |
parents | ab60f3309436 |
children | 8efa9bb96c53 |
comparison
equal
deleted
inserted
replaced
212:ab60f3309436 | 213:36f5cb12e1a2 |
---|---|
10 * Port to the D programming language: | 10 * Port to the D programming language: |
11 * Frank Benoit <benoit@tionex.de> | 11 * Frank Benoit <benoit@tionex.de> |
12 *******************************************************************************/ | 12 *******************************************************************************/ |
13 module dwt.widgets.Scrollable; | 13 module dwt.widgets.Scrollable; |
14 | 14 |
15 import dwt.widgets.Widget; | |
16 import dwt.widgets.Event; | |
17 import dwt.widgets.Control; | |
18 import dwt.widgets.ScrollBar; | |
19 import dwt.widgets.Composite; | |
20 import dwt.DWT; | 15 import dwt.DWT; |
21 import dwt.DWTException; | 16 import dwt.DWTException; |
17 | |
22 import dwt.graphics.Rectangle; | 18 import dwt.graphics.Rectangle; |
19 | |
23 import dwt.internal.win32.OS; | 20 import dwt.internal.win32.OS; |
21 | |
22 import dwt.widgets.Composite; | |
23 import dwt.widgets.Control; | |
24 import dwt.widgets.Decorations; | |
25 import dwt.widgets.Event; | |
26 import dwt.widgets.ScrollBar; | |
27 import dwt.widgets.Widget; | |
24 | 28 |
25 import dwt.dwthelper.utils; | 29 import dwt.dwthelper.utils; |
26 import tango.util.log.Trace; | 30 import tango.util.log.Trace; |
27 void trc( long line ){ | 31 void trc( long line ){ |
28 //Trace.formatln( "Scrollable {}", line ); | 32 //Trace.formatln( "Scrollable {}", line ); |
145 | 149 |
146 override void createWidget () { | 150 override void createWidget () { |
147 super.createWidget (); | 151 super.createWidget (); |
148 if ((style & DWT.H_SCROLL) !is 0) horizontalBar = createScrollBar (DWT.H_SCROLL); | 152 if ((style & DWT.H_SCROLL) !is 0) horizontalBar = createScrollBar (DWT.H_SCROLL); |
149 if ((style & DWT.V_SCROLL) !is 0) verticalBar = createScrollBar (DWT.V_SCROLL); | 153 if ((style & DWT.V_SCROLL) !is 0) verticalBar = createScrollBar (DWT.V_SCROLL); |
154 } | |
155 | |
156 void destroyScrollBar (int type) { | |
157 auto hwnd = scrolledHandle (); | |
158 int bits = OS.GetWindowLong (hwnd, OS.GWL_STYLE); | |
159 if ((type & DWT.HORIZONTAL) !is 0) { | |
160 style &= ~DWT.H_SCROLL; | |
161 bits &= ~OS.WS_HSCROLL; | |
162 } | |
163 if ((type & DWT.VERTICAL) !is 0) { | |
164 style &= ~DWT.V_SCROLL; | |
165 bits &= ~OS.WS_VSCROLL; | |
166 } | |
167 OS.SetWindowLong (hwnd, OS.GWL_STYLE, bits); | |
150 } | 168 } |
151 | 169 |
152 /** | 170 /** |
153 * Returns a rectangle which describes the area of the | 171 * Returns a rectangle which describes the area of the |
154 * receiver which is capable of displaying data (that is, | 172 * receiver which is capable of displaying data (that is, |
276 return result; | 294 return result; |
277 } | 295 } |
278 | 296 |
279 override LRESULT WM_MOUSEWHEEL (int wParam, int lParam) { | 297 override LRESULT WM_MOUSEWHEEL (int wParam, int lParam) { |
280 trc(__LINE__); | 298 trc(__LINE__); |
299 int scrollRemainder = display.scrollRemainder; | |
281 LRESULT result = super.WM_MOUSEWHEEL (wParam, lParam); | 300 LRESULT result = super.WM_MOUSEWHEEL (wParam, lParam); |
282 if (result !is null) return result; | 301 if (result !is null) return result; |
283 | |
284 /* | 302 /* |
285 * Translate WM_MOUSEWHEEL to WM_VSCROLL or WM_HSCROLL. | 303 * Translate WM_MOUSEWHEEL to WM_VSCROLL or WM_HSCROLL. |
286 */ | 304 */ |
287 if ((state & CANVAS) !is 0) { | 305 if ((state & CANVAS) !is 0) { |
288 if ((wParam & (OS.MK_SHIFT | OS.MK_CONTROL)) !is 0) return result; | 306 if ((wParam & (OS.MK_SHIFT | OS.MK_CONTROL)) !is 0) return result; |
289 bool vertical = verticalBar !is null && verticalBar.getEnabled (); | 307 bool vertical = verticalBar !is null && verticalBar.getEnabled (); |
290 bool horizontal = horizontalBar !is null && horizontalBar.getEnabled (); | 308 bool horizontal = horizontalBar !is null && horizontalBar.getEnabled (); |
291 int msg = (vertical) ? OS.WM_VSCROLL : (horizontal) ? OS.WM_HSCROLL : 0; | 309 int msg = vertical ? OS.WM_VSCROLL : horizontal ? OS.WM_HSCROLL : 0; |
292 if (msg is 0) return result; | 310 if (msg is 0) return result; |
293 int value; | 311 int linesToScroll; |
294 OS.SystemParametersInfo (OS.SPI_GETWHEELSCROLLLINES, 0, &value, 0); | 312 OS.SystemParametersInfo (OS.SPI_GETWHEELSCROLLLINES, 0, &linesToScroll, 0); |
295 int delta = cast(short) (wParam >> 16); | 313 int delta = OS.GET_WHEEL_DELTA_WPARAM (wParam); |
296 int code = 0, count = 0; | 314 bool pageScroll = linesToScroll is OS.WHEEL_PAGESCROLL; |
297 if (value is OS.WHEEL_PAGESCROLL) { | 315 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { |
298 code = delta < 0 ? OS.SB_PAGEDOWN : OS.SB_PAGEUP; | 316 ScrollBar bar = vertical ? verticalBar : horizontalBar; |
299 count = Math.abs (delta / OS.WHEEL_DELTA); | 317 SCROLLINFO info; |
318 info.cbSize = SCROLLINFO.sizeof; | |
319 info.fMask = OS.SIF_POS; | |
320 OS.GetScrollInfo (handle, bar.scrollBarType (), &info); | |
321 if (vertical && !pageScroll) delta *= linesToScroll; | |
322 int increment = pageScroll ? bar.getPageIncrement () : bar.getIncrement (); | |
323 info.nPos -= increment * delta / OS.WHEEL_DELTA; | |
324 OS.SetScrollInfo (handle, bar.scrollBarType (), &info, true); | |
325 OS.SendMessage (handle, msg, OS.SB_THUMBPOSITION, 0); | |
300 } else { | 326 } else { |
301 code = delta < 0 ? OS.SB_LINEDOWN : OS.SB_LINEUP; | 327 int code = 0; |
302 delta = Math.abs (delta); | 328 if (pageScroll) { |
303 if (delta < OS.WHEEL_DELTA) return result; | 329 code = delta < 0 ? OS.SB_PAGEDOWN : OS.SB_PAGEUP; |
304 if (msg is OS.WM_VSCROLL) { | |
305 count = value * delta / OS.WHEEL_DELTA; | |
306 } else { | 330 } else { |
307 count = delta / OS.WHEEL_DELTA; | 331 code = delta < 0 ? OS.SB_LINEDOWN : OS.SB_LINEUP; |
332 if (msg is OS.WM_VSCROLL) delta *= linesToScroll; | |
308 } | 333 } |
309 } | 334 /* Check if the delta and the remainder have the same direction (sign) */ |
310 for (int i=0; i<count; i++) { | 335 if ((delta ^ scrollRemainder) >= 0) delta += scrollRemainder; |
311 OS.SendMessage (handle, msg, code, 0); | 336 int count = Math.abs (delta) / OS.WHEEL_DELTA; |
337 for (int i=0; i<count; i++) { | |
338 OS.SendMessage (handle, msg, code, 0); | |
339 } | |
312 } | 340 } |
313 return LRESULT.ZERO; | 341 return LRESULT.ZERO; |
314 } | 342 } |
315 | 343 |
316 /* | 344 /* |
324 * then the application has already been notified. If not | 352 * then the application has already been notified. If not |
325 * explicitly send the event. | 353 * explicitly send the event. |
326 */ | 354 */ |
327 int vPosition = verticalBar is null ? 0 : verticalBar.getSelection (); | 355 int vPosition = verticalBar is null ? 0 : verticalBar.getSelection (); |
328 int hPosition = horizontalBar is null ? 0 : horizontalBar.getSelection (); | 356 int hPosition = horizontalBar is null ? 0 : horizontalBar.getSelection (); |
329 int code = callWindowProc (handle, OS.WM_MOUSEWHEEL, wParam, lParam); | 357 int /*long*/ code = callWindowProc (handle, OS.WM_MOUSEWHEEL, wParam, lParam); |
330 if (verticalBar !is null) { | 358 if (verticalBar !is null) { |
331 int position = verticalBar.getSelection (); | 359 int position = verticalBar.getSelection (); |
332 if (position !is vPosition) { | 360 if (position !is vPosition) { |
333 Event event = new Event (); | 361 Event event = new Event (); |
334 event.detail = position < vPosition ? DWT.PAGE_UP : DWT.PAGE_DOWN; | 362 event.detail = position < vPosition ? DWT.PAGE_UP : DWT.PAGE_DOWN; |
346 return new LRESULT (code); | 374 return new LRESULT (code); |
347 } | 375 } |
348 | 376 |
349 override LRESULT WM_SIZE (int wParam, int lParam) { | 377 override LRESULT WM_SIZE (int wParam, int lParam) { |
350 trc(__LINE__); | 378 trc(__LINE__); |
351 int code = callWindowProc (handle, OS.WM_SIZE, wParam, lParam); | 379 int /*long*/ code = callWindowProc (handle, OS.WM_SIZE, wParam, lParam); |
352 super.WM_SIZE (wParam, lParam); | 380 super.WM_SIZE (wParam, lParam); |
353 // widget may be disposed at this point | 381 // widget may be disposed at this point |
354 if (code is 0) return LRESULT.ZERO; | 382 if (code is 0) return LRESULT.ZERO; |
355 return new LRESULT (code); | 383 return new LRESULT (code); |
356 } | 384 } |
370 return wmScroll (verticalBar, (state & CANVAS) !is 0, handle, OS.WM_VSCROLL, wParam, lParam); | 398 return wmScroll (verticalBar, (state & CANVAS) !is 0, handle, OS.WM_VSCROLL, wParam, lParam); |
371 } | 399 } |
372 return result; | 400 return result; |
373 } | 401 } |
374 | 402 |
375 LRESULT wmScroll (ScrollBar bar, bool update, HWND hwnd, int msg, int wParam, int lParam) { | 403 LRESULT wmNCPaint (HWND hwnd, int /*long*/ wParam, int /*long*/ lParam) { |
376 trc(__LINE__); | 404 LRESULT result = super.wmNCPaint (hwnd, wParam, lParam); |
405 if (result !is null) return result; | |
406 /* | |
407 * Bug in Windows. On XP only (not Vista), Windows sometimes | |
408 * does not redraw the bottom right corner of a window that | |
409 * has scroll bars, causing pixel corruption. The fix is to | |
410 * always draw the corner. | |
411 */ | |
412 if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { | |
413 if (!OS.IsWinCE && OS.WIN32_VERSION < OS.VERSION (6, 0)) { | |
414 int bits1 = OS.GetWindowLong (hwnd, OS.GWL_STYLE); | |
415 if ((bits1 & (OS.WS_HSCROLL | OS.WS_VSCROLL)) !is 0) { | |
416 RECT windowRect; | |
417 OS.GetWindowRect (hwnd, &windowRect); | |
418 RECT trimRect; | |
419 int bits2 = OS.GetWindowLong (hwnd, OS.GWL_EXSTYLE); | |
420 OS.AdjustWindowRectEx (&trimRect, bits1, false, bits2); | |
421 bool hVisible = false, vVisible = false; | |
422 SCROLLBARINFO psbi; | |
423 psbi.cbSize = SCROLLBARINFO.sizeof; | |
424 if (OS.GetScrollBarInfo (hwnd, OS.OBJID_HSCROLL, &psbi)) { | |
425 hVisible = (psbi.rgstate [0] & OS.STATE_SYSTEM_INVISIBLE) is 0; | |
426 } | |
427 if (OS.GetScrollBarInfo (hwnd, OS.OBJID_VSCROLL, &psbi)) { | |
428 vVisible = (psbi.rgstate [0] & OS.STATE_SYSTEM_INVISIBLE) is 0; | |
429 } | |
430 RECT cornerRect; | |
431 cornerRect.right = windowRect.right - windowRect.left - trimRect.right; | |
432 cornerRect.bottom = windowRect.bottom - windowRect.top - trimRect.bottom; | |
433 cornerRect.left = cornerRect.right - (hVisible ? OS.GetSystemMetrics (OS.SM_CXVSCROLL) : 0); | |
434 cornerRect.top = cornerRect.bottom - (vVisible ? OS.GetSystemMetrics (OS.SM_CYHSCROLL) : 0); | |
435 if (cornerRect.left !is cornerRect.right && cornerRect.top !is cornerRect.bottom) { | |
436 auto hDC = OS.GetWindowDC (hwnd); | |
437 OS.FillRect (hDC, &cornerRect, cast(HANDLE)( OS.COLOR_BTNFACE + 1)); | |
438 Decorations shell = menuShell (); | |
439 if ((shell.style & DWT.RESIZE) !is 0) { | |
440 auto hwndScroll = shell.scrolledHandle (); | |
441 bool drawGripper = hwnd is hwndScroll; | |
442 if (!drawGripper) { | |
443 RECT shellRect; | |
444 OS.GetClientRect (hwndScroll, &shellRect); | |
445 OS.MapWindowPoints (hwndScroll, null, cast(POINT*)&shellRect, 2); | |
446 drawGripper = shellRect.right is windowRect.right && shellRect.bottom is windowRect.bottom; | |
447 } | |
448 if (drawGripper) { | |
449 OS.DrawThemeBackground (display.hScrollBarTheme(), hDC, OS.SBP_SIZEBOX, 0, &cornerRect, null); | |
450 } | |
451 } | |
452 OS.ReleaseDC (hwnd, hDC); | |
453 } | |
454 } | |
455 } | |
456 } | |
457 return result; | |
458 } | |
459 | |
460 LRESULT wmScroll (ScrollBar bar, bool update, HWND hwnd, int msg, int /*long*/ wParam, int /*long*/ lParam) { | |
377 LRESULT result = null; | 461 LRESULT result = null; |
378 if (update) { | 462 if (update) { |
379 int type = msg is OS.WM_HSCROLL ? OS.SB_HORZ : OS.SB_VERT; | 463 int type = msg is OS.WM_HSCROLL ? OS.SB_HORZ : OS.SB_VERT; |
380 SCROLLINFO info; | 464 SCROLLINFO info; |
381 info.cbSize = SCROLLINFO.sizeof; | 465 info.cbSize = SCROLLINFO.sizeof; |
382 info.fMask = OS.SIF_TRACKPOS | OS.SIF_POS | OS.SIF_RANGE; | 466 info.fMask = OS.SIF_TRACKPOS | OS.SIF_POS | OS.SIF_RANGE; |
383 OS.GetScrollInfo (hwnd, type, &info); | 467 OS.GetScrollInfo (hwnd, type, &info); |
384 info.fMask = OS.SIF_POS; | 468 info.fMask = OS.SIF_POS; |
385 int code = wParam & 0xFFFF; | 469 int code = OS.LOWORD (wParam); |
386 switch (code) { | 470 switch (code) { |
387 case OS.SB_ENDSCROLL: return null; | 471 case OS.SB_ENDSCROLL: return null; |
388 case OS.SB_THUMBPOSITION: | 472 case OS.SB_THUMBPOSITION: |
389 case OS.SB_THUMBTRACK: | 473 case OS.SB_THUMBTRACK: |
390 /* | 474 /* |
417 break; | 501 break; |
418 default: | 502 default: |
419 } | 503 } |
420 OS.SetScrollInfo (hwnd, type, &info, true); | 504 OS.SetScrollInfo (hwnd, type, &info, true); |
421 } else { | 505 } else { |
422 int code = callWindowProc (hwnd, msg, wParam, lParam); | 506 int /*long*/ code = callWindowProc (hwnd, msg, wParam, lParam); |
423 result = code is 0 ? LRESULT.ZERO : new LRESULT (code); | 507 result = code is 0 ? LRESULT.ZERO : new LRESULT (code); |
424 } | 508 } |
425 bar.wmScrollChild (wParam, lParam); | 509 bar.wmScrollChild (wParam, lParam); |
426 return result; | 510 return result; |
427 } | 511 } |