comparison dwt/widgets/Sash.d @ 0:380af2bdd8e5

Upload of whole dwt tree
author Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com>
date Sat, 09 Aug 2008 17:00:02 +0200
parents
children 649b8e223d5a
comparison
equal deleted inserted replaced
-1:000000000000 0:380af2bdd8e5
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 module dwt.widgets.Sash;
12
13 import dwt.dwthelper.utils;
14
15 import dwt.DWT;
16 import dwt.DWTException;
17 import dwt.events.SelectionEvent;
18 import dwt.events.SelectionListener;
19 import dwt.graphics.Cursor;
20 import dwt.graphics.Point;
21 import dwt.graphics.Rectangle;
22 import dwt.internal.cocoa.NSEvent;
23 import dwt.internal.cocoa.NSPoint;
24 import dwt.internal.cocoa.NSRect;
25 import dwt.internal.cocoa.OS;
26 import dwt.internal.cocoa.SWTView;
27
28 /**
29 * Instances of the receiver represent a selectable user interface object
30 * that allows the user to drag a rubber banded outline of the sash within
31 * the parent control.
32 * <dl>
33 * <dt><b>Styles:</b></dt>
34 * <dd>HORIZONTAL, VERTICAL, SMOOTH</dd>
35 * <dt><b>Events:</b></dt>
36 * <dd>Selection</dd>
37 * </dl>
38 * <p>
39 * Note: Only one of the styles HORIZONTAL and VERTICAL may be specified.
40 * </p><p>
41 * IMPORTANT: This class is intended to be subclassed <em>only</em>
42 * within the DWT implementation.
43 * </p>
44 */
45 public class Sash extends Control {
46 Cursor sizeCursor;
47 bool dragging;
48 int lastX, lastY, startX, startY;
49 private final static int INCREMENT = 1;
50 private final static int PAGE_INCREMENT = 9;
51
52 /**
53 * Constructs a new instance of this class given its parent
54 * and a style value describing its behavior and appearance.
55 * <p>
56 * The style value is either one of the style constants defined in
57 * class <code>DWT</code> which is applicable to instances of this
58 * class, or must be built by <em>bitwise OR</em>'ing together
59 * (that is, using the <code>int</code> "|" operator) two or more
60 * of those <code>DWT</code> style constants. The class description
61 * lists the style constants that are applicable to the class.
62 * Style bits are also inherited from superclasses.
63 * </p>
64 *
65 * @param parent a composite control which will be the parent of the new instance (cannot be null)
66 * @param style the style of control to construct
67 *
68 * @exception IllegalArgumentException <ul>
69 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
70 * </ul>
71 * @exception DWTException <ul>
72 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
73 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
74 * </ul>
75 *
76 * @see DWT#HORIZONTAL
77 * @see DWT#VERTICAL
78 * @see Widget#checkSubclass
79 * @see Widget#getStyle
80 */
81 public Sash (Composite parent, int style) {
82 super (parent, checkStyle (style));
83 int cursorStyle = (style & DWT.VERTICAL) !is 0 ? DWT.CURSOR_SIZEWE : DWT.CURSOR_SIZENS;
84 sizeCursor = new Cursor (display, cursorStyle);
85 }
86
87 /**
88 * Adds the listener to the collection of listeners who will
89 * be notified when the control is selected by the user, by sending
90 * it one of the messages defined in the <code>SelectionListener</code>
91 * interface.
92 * <p>
93 * When <code>widgetSelected</code> is called, the x, y, width, and height fields of the event object are valid.
94 * If the receiver is being dragged, the event object detail field contains the value <code>DWT.DRAG</code>.
95 * <code>widgetDefaultSelected</code> is not called.
96 * </p>
97 *
98 * @param listener the listener which should be notified when the control is selected by the user
99 *
100 * @exception IllegalArgumentException <ul>
101 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
102 * </ul>
103 * @exception DWTException <ul>
104 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
105 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
106 * </ul>
107 *
108 * @see SelectionListener
109 * @see #removeSelectionListener
110 * @see SelectionEvent
111 */
112 public void addSelectionListener(SelectionListener listener) {
113 checkWidget();
114 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT);
115 TypedListener typedListener = new TypedListener(listener);
116 addListener(DWT.Selection,typedListener);
117 addListener(DWT.DefaultSelection,typedListener);
118 }
119
120 static int checkStyle (int style) {
121 /*
122 * Macintosh only supports smooth dragging.
123 */
124 style |= DWT.SMOOTH;
125 return checkBits (style, DWT.HORIZONTAL, DWT.VERTICAL, 0, 0, 0, 0);
126 }
127
128 bool becomeFirstResponder () {
129 bool result = super.becomeFirstResponder();
130 NSRect frame = view.frame();
131 lastX = (int)frame.x;
132 lastY = (int)frame.y;
133 return result;
134 }
135
136 public Point computeSize (int wHint, int hHint, bool changed) {
137 checkWidget();
138 int width = 0, height = 0;
139 if ((style & DWT.HORIZONTAL) !is 0) {
140 width += DEFAULT_WIDTH; height += 5;
141 } else {
142 width += 5; height += DEFAULT_HEIGHT;
143 }
144 if (wHint !is DWT.DEFAULT) width = wHint;
145 if (hHint !is DWT.DEFAULT) height = hHint;
146 return new Point (width, height);
147 }
148
149 void createHandle () {
150 SWTView widget = (SWTView)new SWTView().alloc();
151 widget.initWithFrame (new NSRect());
152 widget.setTag(jniRef);
153 view = widget;
154 parent.contentView().addSubview_(view);
155 }
156
157 bool sendKeyEvent(NSEvent nsEvent, int type) {
158 //TODO consumed
159 int keyCode = nsEvent.keyCode();
160 switch (keyCode) {
161 case 126: /* Up arrow */
162 case 123: /* Left arrow */
163 case 125: /* Down arrow */
164 case 124: /* Right arrow */ {
165 int xChange = 0, yChange = 0;
166 int stepSize = PAGE_INCREMENT;
167 int modifiers = nsEvent.modifierFlags();
168 if ((modifiers & OS.NSControlKeyMask) !is 0) stepSize = INCREMENT;
169 if ((style & DWT.VERTICAL) !is 0) {
170 if (keyCode is 126 || keyCode is 125) break;
171 xChange = keyCode is 123 ? -stepSize : stepSize;
172 } else {
173 if (keyCode is 123 || keyCode is 124) break;
174 yChange = keyCode is 126 ? -stepSize : stepSize;
175 }
176
177 Rectangle bounds = getBounds ();
178 int width = bounds.width, height = bounds.height;
179 Rectangle parentBounds = parent.getBounds ();
180 int parentWidth = parentBounds.width;
181 int parentHeight = parentBounds.height;
182 int newX = lastX, newY = lastY;
183 if ((style & DWT.VERTICAL) !is 0) {
184 newX = Math.min (Math.max (0, lastX + xChange), parentWidth - width);
185 } else {
186 newY = Math.min (Math.max (0, lastY + yChange), parentHeight - height);
187 }
188 if (newX is lastX && newY is lastY) return true;
189 Event event = new Event ();
190 event.x = newX;
191 event.y = newY;
192 event.width = width;
193 event.height = height;
194 sendEvent (DWT.Selection, event);
195 if (isDisposed ()) break;
196 if (event.doit) {
197 setBounds (event.x, event.y, width, height);
198 if (isDisposed ()) break;
199 lastX = event.x;
200 lastY = event.y;
201 if (isDisposed ()) return false;
202 int cursorX = event.x, cursorY = event.y;
203 if ((style & DWT.VERTICAL) !is 0) {
204 cursorY += height / 2;
205 } else {
206 cursorX += width / 2;
207 }
208 display.setCursorLocation (parent.toDisplay (cursorX, cursorY));
209 }
210 break;
211 }
212 }
213 return true;
214 }
215
216 void mouseDown(int theEvent) {
217 super.mouseDown(theEvent);
218 NSEvent nsEvent = new NSEvent(theEvent);
219 if (nsEvent.clickCount() !is 1) return;
220 NSPoint location = nsEvent.locationInWindow();
221 NSPoint point = view.convertPoint_fromView_(location, null);
222 startX = (int)point.x;
223 startY = (int)point.y;
224 NSRect frame = view.frame();
225 Event event = new Event ();
226 event.x = (int)frame.x;
227 event.y = (int)frame.y;
228 event.width = (int)frame.width;
229 event.height = (int)frame.height;
230 sendEvent (DWT.Selection, event);
231 if (isDisposed ()) return;
232 if (event.doit) {
233 lastX = event.x;
234 lastY = event.y;
235 dragging = true;
236 setLocation(event.x, event.y);
237 }
238 }
239
240 void mouseDragged(int theEvent) {
241 super.mouseDragged(theEvent);
242 if (!dragging) return;
243 NSEvent nsEvent = new NSEvent(theEvent);
244 NSPoint location = nsEvent.locationInWindow();
245 NSPoint point = view.convertPoint_fromView_(location, null);
246 NSRect frame = view.frame();
247 NSRect parentFrame = parent.topView().frame();
248 int newX = lastX, newY = lastY;
249 if ((style & DWT.VERTICAL) !is 0) {
250 newX = Math.min (Math.max (0, (int)(point.x + frame.x - startX)), (int)(parentFrame.width - frame.width));
251 } else {
252 newY = Math.min (Math.max (0, (int)(point.y + frame.y - startY)), (int)(parentFrame.height - frame.height));
253 }
254 if (newX is lastX && newY is lastY) return;
255 Event event = new Event ();
256 event.x = newX;
257 event.y = newY;
258 event.width = (int)frame.width;
259 event.height = (int)frame.height;
260 sendEvent (DWT.Selection, event);
261 if (isDisposed ()) return;
262 if (event.doit) {
263 lastX = event.x;
264 lastY = event.y;
265 setBounds (event.x, event.y, (int)frame.width, (int)frame.height);
266 }
267 }
268
269 void mouseEntered(int theEvent) {
270 //TODO need to add tracking area
271 super.mouseEntered(theEvent);
272 sizeCursor.handle.set();
273 }
274
275 void mouseUp(int theEvent) {
276 super.mouseUp(theEvent);
277 if (!dragging) return;
278 dragging = false;
279 NSRect frame = view.frame();
280 Event event = new Event ();
281 event.x = lastX;
282 event.y = lastY;
283 event.width = (int)frame.width;
284 event.height = (int)frame.height;
285 sendEvent (DWT.Selection, event);
286 if (isDisposed ()) return;
287 if (event.doit) {
288 setBounds (event.x, event.y, (int)frame.width, (int)frame.height);
289 }
290 }
291
292 void releaseWidget () {
293 super.releaseWidget ();
294 if (sizeCursor !is null) sizeCursor.dispose ();
295 sizeCursor = null;
296 }
297
298 /**
299 * Removes the listener from the collection of listeners who will
300 * be notified when the control is selected by the user.
301 *
302 * @param listener the listener which should no longer be notified
303 *
304 * @exception IllegalArgumentException <ul>
305 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
306 * </ul>
307 * @exception DWTException <ul>
308 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
309 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
310 * </ul>
311 *
312 * @see SelectionListener
313 * @see #addSelectionListener
314 */
315 public void removeSelectionListener(SelectionListener listener) {
316 checkWidget();
317 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT);
318 if (eventTable is null) return;
319 eventTable.unhook(DWT.Selection, listener);
320 eventTable.unhook(DWT.DefaultSelection,listener);
321 }
322
323 int traversalCode (int key, NSEvent theEvent) {
324 return 0;
325 }
326
327 }