KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > widgets > Sash


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.swt.widgets;
12
13  
14 import org.eclipse.swt.internal.win32.*;
15 import org.eclipse.swt.*;
16 import org.eclipse.swt.graphics.*;
17 import org.eclipse.swt.events.*;
18
19 /**
20  * Instances of the receiver represent a selectable user interface object
21  * that allows the user to drag a rubber banded outline of the sash within
22  * the parent control.
23  * <dl>
24  * <dt><b>Styles:</b></dt>
25  * <dd>HORIZONTAL, VERTICAL, SMOOTH</dd>
26  * <dt><b>Events:</b></dt>
27  * <dd>Selection</dd>
28  * </dl>
29  * <p>
30  * Note: Only one of the styles HORIZONTAL and VERTICAL may be specified.
31  * </p><p>
32  * IMPORTANT: This class is intended to be subclassed <em>only</em>
33  * within the SWT implementation.
34  * </p>
35  */

36 public class Sash extends Control {
37     boolean dragging;
38     int startX, startY, lastX, lastY;
39     final static int INCREMENT = 1;
40     final static int PAGE_INCREMENT = 9;
41
42 /**
43  * Constructs a new instance of this class given its parent
44  * and a style value describing its behavior and appearance.
45  * <p>
46  * The style value is either one of the style constants defined in
47  * class <code>SWT</code> which is applicable to instances of this
48  * class, or must be built by <em>bitwise OR</em>'ing together
49  * (that is, using the <code>int</code> "|" operator) two or more
50  * of those <code>SWT</code> style constants. The class description
51  * lists the style constants that are applicable to the class.
52  * Style bits are also inherited from superclasses.
53  * </p>
54  *
55  * @param parent a composite control which will be the parent of the new instance (cannot be null)
56  * @param style the style of control to construct
57  *
58  * @exception IllegalArgumentException <ul>
59  * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
60  * </ul>
61  * @exception SWTException <ul>
62  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
63  * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
64  * </ul>
65  *
66  * @see SWT#HORIZONTAL
67  * @see SWT#VERTICAL
68  * @see Widget#checkSubclass
69  * @see Widget#getStyle
70  */

71 public Sash (Composite parent, int style) {
72     super (parent, checkStyle (style));
73 }
74
75 /**
76  * Adds the listener to the collection of listeners who will
77  * be notified when the control is selected by the user, by sending
78  * it one of the messages defined in the <code>SelectionListener</code>
79  * interface.
80  * <p>
81  * When <code>widgetSelected</code> is called, the x, y, width, and height fields of the event object are valid.
82  * If the receiver is being dragged, the event object detail field contains the value <code>SWT.DRAG</code>.
83  * <code>widgetDefaultSelected</code> is not called.
84  * </p>
85  *
86  * @param listener the listener which should be notified when the control is selected by the user
87  *
88  * @exception IllegalArgumentException <ul>
89  * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
90  * </ul>
91  * @exception SWTException <ul>
92  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
93  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
94  * </ul>
95  *
96  * @see SelectionListener
97  * @see #removeSelectionListener
98  * @see SelectionEvent
99  */

100 public void addSelectionListener (SelectionListener listener) {
101     checkWidget ();
102     if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
103     TypedListener typedListener = new TypedListener (listener);
104     addListener (SWT.Selection,typedListener);
105     addListener (SWT.DefaultSelection,typedListener);
106 }
107
108 int callWindowProc (int hwnd, int msg, int wParam, int lParam) {
109     if (handle == 0) return 0;
110     return OS.DefWindowProc (hwnd, msg, wParam, lParam);
111 }
112
113 void createHandle () {
114     super.createHandle ();
115     state |= THEME_BACKGROUND;
116 }
117
118 static int checkStyle (int style) {
119     return checkBits (style, SWT.HORIZONTAL, SWT.VERTICAL, 0, 0, 0, 0);
120 }
121
122 public Point computeSize (int wHint, int hHint, boolean changed) {
123     checkWidget ();
124     int border = getBorderWidth ();
125     int width = border * 2, height = border * 2;
126     if ((style & SWT.HORIZONTAL) != 0) {
127         width += DEFAULT_WIDTH; height += 3;
128     } else {
129         width += 3; height += DEFAULT_HEIGHT;
130     }
131     if (wHint != SWT.DEFAULT) width = wHint + (border * 2);
132     if (hHint != SWT.DEFAULT) height = hHint + (border * 2);
133     return new Point (width, height);
134 }
135
136 void drawBand (int x, int y, int width, int height) {
137     if ((style & SWT.SMOOTH) != 0) return;
138     int hwndTrack = parent.handle;
139     byte [] bits = {-86, 0, 85, 0, -86, 0, 85, 0, -86, 0, 85, 0, -86, 0, 85, 0};
140     int stippleBitmap = OS.CreateBitmap (8, 8, 1, 1, bits);
141     int stippleBrush = OS.CreatePatternBrush (stippleBitmap);
142     int hDC = OS.GetDCEx (hwndTrack, 0, OS.DCX_CACHE);
143     int oldBrush = OS.SelectObject (hDC, stippleBrush);
144     OS.PatBlt (hDC, x, y, width, height, OS.PATINVERT);
145     OS.SelectObject (hDC, oldBrush);
146     OS.ReleaseDC (hwndTrack, hDC);
147     OS.DeleteObject (stippleBrush);
148     OS.DeleteObject (stippleBitmap);
149 }
150
151 /**
152  * Removes the listener from the collection of listeners who will
153  * be notified when the control is selected by the user.
154  *
155  * @param listener the listener which should no longer be notified
156  *
157  * @exception IllegalArgumentException <ul>
158  * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
159  * </ul>
160  * @exception SWTException <ul>
161  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
162  * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
163  * </ul>
164  *
165  * @see SelectionListener
166  * @see #addSelectionListener
167  */

168 public void removeSelectionListener(SelectionListener listener) {
169     checkWidget ();
170     if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
171     if (eventTable == null) return;
172     eventTable.unhook (SWT.Selection, listener);
173     eventTable.unhook (SWT.DefaultSelection,listener);
174 }
175
176 TCHAR windowClass () {
177     return display.windowClass;
178 }
179
180 int windowProc () {
181     return display.windowProc;
182 }
183
184 LRESULT WM_ERASEBKGND (int wParam, int lParam) {
185     super.WM_ERASEBKGND (wParam, lParam);
186     drawBackground (wParam);
187     return LRESULT.ONE;
188 }
189
190 LRESULT WM_KEYDOWN (int wParam, int lParam) {
191     LRESULT result = super.WM_KEYDOWN (wParam, lParam);
192     if (result != null) return result;
193     switch (wParam) {
194         case OS.VK_LEFT:
195         case OS.VK_RIGHT:
196         case OS.VK_UP:
197         case OS.VK_DOWN:
198             
199             /* Calculate the new x or y position */
200             if (OS.GetKeyState (OS.VK_LBUTTON) < 0) return result;
201             int step = OS.GetKeyState (OS.VK_CONTROL) < 0 ? INCREMENT : PAGE_INCREMENT;
202             POINT pt = new POINT ();
203             if ((style & SWT.VERTICAL) != 0) {
204                 if (wParam == OS.VK_UP || wParam == OS.VK_DOWN) break;
205                 pt.x = wParam == OS.VK_LEFT ? -step : step;
206             } else {
207                 if (wParam == OS.VK_LEFT || wParam == OS.VK_RIGHT) break;
208                 pt.y = wParam == OS.VK_UP ? -step : step;
209             }
210             int hwndTrack = parent.handle;
211             OS.MapWindowPoints (handle, hwndTrack, pt, 1);
212             RECT rect = new RECT (), clientRect = new RECT ();
213             OS.GetWindowRect (handle, rect);
214             int width = rect.right - rect.left;
215             int height = rect.bottom - rect.top;
216             OS.GetClientRect (hwndTrack, clientRect);
217             int clientWidth = clientRect.right - clientRect.left;
218             int clientHeight = clientRect.bottom - clientRect.top;
219             int newX = lastX, newY = lastY;
220             if ((style & SWT.VERTICAL) != 0) {
221                 newX = Math.min (Math.max (0, pt.x - startX), clientWidth - width);
222             } else {
223                 newY = Math.min (Math.max (0, pt.y - startY), clientHeight - height);
224             }
225             if (newX == lastX && newY == lastY) return result;
226
227             /* Update the pointer position */
228             POINT cursorPt = new POINT ();
229             cursorPt.x = pt.x; cursorPt.y = pt.y;
230             OS.ClientToScreen (hwndTrack, cursorPt);
231             if ((style & SWT.VERTICAL) != 0) {
232                 cursorPt.y += height / 2;
233             }
234             else {
235                 cursorPt.x += width / 2;
236             }
237             OS.SetCursorPos (cursorPt.x, cursorPt.y);
238
239             Event event = new Event ();
240             event.x = newX;
241             event.y = newY;
242             event.width = width;
243             event.height = height;
244             sendEvent (SWT.Selection, event);
245             if (isDisposed ()) return LRESULT.ZERO;
246             if (event.doit) {
247                 if ((style & SWT.SMOOTH) != 0) {
248                     setBounds (event.x, event.y, width, height);
249                 }
250             }
251             return result;
252     }
253     return result;
254 }
255
256 LRESULT WM_GETDLGCODE (int wParam, int lParam) {
257     return new LRESULT (OS.DLGC_STATIC);
258 }
259
260 LRESULT WM_LBUTTONDOWN (int wParam, int lParam) {
261     LRESULT result = super.WM_LBUTTONDOWN (wParam, lParam);
262     if (result == LRESULT.ZERO) return result;
263
264     /* Compute the banding rectangle */
265     int hwndTrack = parent.handle;
266     POINT pt = new POINT ();
267     pt.x = (short) (lParam & 0xFFFF);
268     pt.y = (short) (lParam >> 16);
269     RECT rect = new RECT ();
270     OS.GetWindowRect (handle, rect);
271     OS.MapWindowPoints (handle, 0, pt, 1);
272     startX = pt.x - rect.left;
273     startY = pt.y - rect.top;
274     OS.MapWindowPoints (0, hwndTrack, rect, 2);
275     lastX = rect.left;
276     lastY = rect.top;
277     int width = rect.right - rect.left;
278     int height = rect.bottom - rect.top;
279
280     /* The event must be sent because doit flag is used */
281     Event event = new Event ();
282     event.x = lastX;
283     event.y = lastY;
284     event.width = width;
285     event.height = height;
286     if ((style & SWT.SMOOTH) == 0) {
287         event.detail = SWT.DRAG;
288     }
289     sendEvent (SWT.Selection, event);
290     if (isDisposed ()) return LRESULT.ZERO;
291     
292     /* Draw the banding rectangle */
293     if (event.doit) {
294         dragging = true;
295         lastX = event.x;
296         lastY = event.y;
297         menuShell ().bringToTop ();
298         if (isDisposed ()) return LRESULT.ZERO;
299         if (OS.IsWinCE) {
300             OS.UpdateWindow (hwndTrack);
301         } else {
302             int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN;
303             OS.RedrawWindow (hwndTrack, null, 0, flags);
304         }
305         drawBand (event.x, event.y, width, height);
306         if ((style & SWT.SMOOTH) != 0) {
307             setBounds (event.x, event.y, width, height);
308             // widget could be disposed at this point
309
}
310     }
311     return result;
312 }
313
314 LRESULT WM_LBUTTONUP (int wParam, int lParam) {
315     LRESULT result = super.WM_LBUTTONUP (wParam, lParam);
316     if (result == LRESULT.ZERO) return result;
317
318     /* Compute the banding rectangle */
319     if (!dragging) return result;
320     dragging = false;
321     RECT rect = new RECT ();
322     OS.GetWindowRect (handle, rect);
323     int width = rect.right - rect.left;
324     int height = rect.bottom - rect.top;
325     
326     /* The event must be sent because doit flag is used */
327     Event event = new Event ();
328     event.x = lastX;
329     event.y = lastY;
330     event.width = width;
331     event.height = height;
332     drawBand (event.x, event.y, width, height);
333     sendEvent (SWT.Selection, event);
334     if (isDisposed ()) return result;
335     if (event.doit) {
336         if ((style & SWT.SMOOTH) != 0) {
337             setBounds (event.x, event.y, width, height);
338             // widget could be disposed at this point
339
}
340     }
341     return result;
342 }
343
344 LRESULT WM_MOUSEMOVE (int wParam, int lParam) {
345     LRESULT result = super.WM_MOUSEMOVE (wParam, lParam);
346     if (result != null) return result;
347     if (!dragging || (wParam & OS.MK_LBUTTON) == 0) return result;
348
349     /* Compute the banding rectangle */
350     POINT pt = new POINT ();
351     pt.x = (short) (lParam & 0xFFFF);
352     pt.y = (short) (lParam >> 16);
353     int hwndTrack = parent.handle;
354     OS.MapWindowPoints (handle, hwndTrack, pt, 1);
355     RECT rect = new RECT (), clientRect = new RECT ();
356     OS.GetWindowRect (handle, rect);
357     int width = rect.right - rect.left;
358     int height = rect.bottom - rect.top;
359     OS.GetClientRect (hwndTrack, clientRect);
360     int newX = lastX, newY = lastY;
361     if ((style & SWT.VERTICAL) != 0) {
362         int clientWidth = clientRect.right - clientRect.left;
363         newX = Math.min (Math.max (0, pt.x - startX), clientWidth - width);
364     } else {
365         int clientHeight = clientRect.bottom - clientRect.top;
366         newY = Math.min (Math.max (0, pt.y - startY), clientHeight - height);
367     }
368     if (newX == lastX && newY == lastY) return result;
369     drawBand (lastX, lastY, width, height);
370
371     /* The event must be sent because doit flag is used */
372     Event event = new Event ();
373     event.x = newX;
374     event.y = newY;
375     event.width = width;
376     event.height = height;
377     if ((style & SWT.SMOOTH) == 0) {
378         event.detail = SWT.DRAG;
379     }
380     sendEvent (SWT.Selection, event);
381     if (isDisposed ()) return LRESULT.ZERO;
382     if (event.doit) {
383         lastX = event.x;
384         lastY = event.y;
385     }
386     if (OS.IsWinCE) {
387         OS.UpdateWindow (hwndTrack);
388     } else {
389         int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN;
390         OS.RedrawWindow (hwndTrack, null, 0, flags);
391     }
392     drawBand (lastX, lastY, width, height);
393     if ((style & SWT.SMOOTH) != 0) {
394         setBounds (lastX, lastY, width, height);
395         // widget could be disposed at this point
396
}
397     return result;
398 }
399
400 LRESULT WM_SETCURSOR (int wParam, int lParam) {
401     LRESULT result = super.WM_SETCURSOR (wParam, lParam);
402     if (result != null) return result;
403     int hitTest = lParam & 0xFFFF;
404     if (hitTest == OS.HTCLIENT) {
405         int hCursor = 0;
406         if ((style & SWT.HORIZONTAL) != 0) {
407             hCursor = OS.LoadCursor (0, OS.IDC_SIZENS);
408         } else {
409             hCursor = OS.LoadCursor (0, OS.IDC_SIZEWE);
410         }
411         OS.SetCursor (hCursor);
412         return LRESULT.ONE;
413     }
414     return result;
415 }
416
417 }
418
Popular Tags