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 }