Mercurial > projects > dwt-mac
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/widgets/Sash.d Sat Aug 09 17:00:02 2008 +0200 @@ -0,0 +1,327 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +module dwt.widgets.Sash; + +import dwt.dwthelper.utils; + +import dwt.DWT; +import dwt.DWTException; +import dwt.events.SelectionEvent; +import dwt.events.SelectionListener; +import dwt.graphics.Cursor; +import dwt.graphics.Point; +import dwt.graphics.Rectangle; +import dwt.internal.cocoa.NSEvent; +import dwt.internal.cocoa.NSPoint; +import dwt.internal.cocoa.NSRect; +import dwt.internal.cocoa.OS; +import dwt.internal.cocoa.SWTView; + +/** + * Instances of the receiver represent a selectable user interface object + * that allows the user to drag a rubber banded outline of the sash within + * the parent control. + * <dl> + * <dt><b>Styles:</b></dt> + * <dd>HORIZONTAL, VERTICAL, SMOOTH</dd> + * <dt><b>Events:</b></dt> + * <dd>Selection</dd> + * </dl> + * <p> + * Note: Only one of the styles HORIZONTAL and VERTICAL may be specified. + * </p><p> + * IMPORTANT: This class is intended to be subclassed <em>only</em> + * within the DWT implementation. + * </p> + */ +public class Sash extends Control { + Cursor sizeCursor; + bool dragging; + int lastX, lastY, startX, startY; + private final static int INCREMENT = 1; + private final static int PAGE_INCREMENT = 9; + +/** + * Constructs a new instance of this class given its parent + * and a style value describing its behavior and appearance. + * <p> + * The style value is either one of the style constants defined in + * class <code>DWT</code> which is applicable to instances of this + * class, or must be built by <em>bitwise OR</em>'ing together + * (that is, using the <code>int</code> "|" operator) two or more + * of those <code>DWT</code> style constants. The class description + * lists the style constants that are applicable to the class. + * Style bits are also inherited from superclasses. + * </p> + * + * @param parent a composite control which will be the parent of the new instance (cannot be null) + * @param style the style of control to construct + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> + * </ul> + * @exception DWTException <ul> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> + * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> + * </ul> + * + * @see DWT#HORIZONTAL + * @see DWT#VERTICAL + * @see Widget#checkSubclass + * @see Widget#getStyle + */ +public Sash (Composite parent, int style) { + super (parent, checkStyle (style)); + int cursorStyle = (style & DWT.VERTICAL) !is 0 ? DWT.CURSOR_SIZEWE : DWT.CURSOR_SIZENS; + sizeCursor = new Cursor (display, cursorStyle); +} + +/** + * Adds the listener to the collection of listeners who will + * be notified when the control is selected by the user, by sending + * it one of the messages defined in the <code>SelectionListener</code> + * interface. + * <p> + * When <code>widgetSelected</code> is called, the x, y, width, and height fields of the event object are valid. + * If the receiver is being dragged, the event object detail field contains the value <code>DWT.DRAG</code>. + * <code>widgetDefaultSelected</code> is not called. + * </p> + * + * @param listener the listener which should be notified when the control is selected by the user + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> + * </ul> + * @exception DWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @see SelectionListener + * @see #removeSelectionListener + * @see SelectionEvent + */ +public void addSelectionListener(SelectionListener listener) { + checkWidget(); + if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); + TypedListener typedListener = new TypedListener(listener); + addListener(DWT.Selection,typedListener); + addListener(DWT.DefaultSelection,typedListener); +} + +static int checkStyle (int style) { + /* + * Macintosh only supports smooth dragging. + */ + style |= DWT.SMOOTH; + return checkBits (style, DWT.HORIZONTAL, DWT.VERTICAL, 0, 0, 0, 0); +} + +bool becomeFirstResponder () { + bool result = super.becomeFirstResponder(); + NSRect frame = view.frame(); + lastX = (int)frame.x; + lastY = (int)frame.y; + return result; +} + +public Point computeSize (int wHint, int hHint, bool changed) { + checkWidget(); + int width = 0, height = 0; + if ((style & DWT.HORIZONTAL) !is 0) { + width += DEFAULT_WIDTH; height += 5; + } else { + width += 5; height += DEFAULT_HEIGHT; + } + if (wHint !is DWT.DEFAULT) width = wHint; + if (hHint !is DWT.DEFAULT) height = hHint; + return new Point (width, height); +} + +void createHandle () { + SWTView widget = (SWTView)new SWTView().alloc(); + widget.initWithFrame (new NSRect()); + widget.setTag(jniRef); + view = widget; + parent.contentView().addSubview_(view); +} + +bool sendKeyEvent(NSEvent nsEvent, int type) { + //TODO consumed + int keyCode = nsEvent.keyCode(); + switch (keyCode) { + case 126: /* Up arrow */ + case 123: /* Left arrow */ + case 125: /* Down arrow */ + case 124: /* Right arrow */ { + int xChange = 0, yChange = 0; + int stepSize = PAGE_INCREMENT; + int modifiers = nsEvent.modifierFlags(); + if ((modifiers & OS.NSControlKeyMask) !is 0) stepSize = INCREMENT; + if ((style & DWT.VERTICAL) !is 0) { + if (keyCode is 126 || keyCode is 125) break; + xChange = keyCode is 123 ? -stepSize : stepSize; + } else { + if (keyCode is 123 || keyCode is 124) break; + yChange = keyCode is 126 ? -stepSize : stepSize; + } + + Rectangle bounds = getBounds (); + int width = bounds.width, height = bounds.height; + Rectangle parentBounds = parent.getBounds (); + int parentWidth = parentBounds.width; + int parentHeight = parentBounds.height; + int newX = lastX, newY = lastY; + if ((style & DWT.VERTICAL) !is 0) { + newX = Math.min (Math.max (0, lastX + xChange), parentWidth - width); + } else { + newY = Math.min (Math.max (0, lastY + yChange), parentHeight - height); + } + if (newX is lastX && newY is lastY) return true; + Event event = new Event (); + event.x = newX; + event.y = newY; + event.width = width; + event.height = height; + sendEvent (DWT.Selection, event); + if (isDisposed ()) break; + if (event.doit) { + setBounds (event.x, event.y, width, height); + if (isDisposed ()) break; + lastX = event.x; + lastY = event.y; + if (isDisposed ()) return false; + int cursorX = event.x, cursorY = event.y; + if ((style & DWT.VERTICAL) !is 0) { + cursorY += height / 2; + } else { + cursorX += width / 2; + } + display.setCursorLocation (parent.toDisplay (cursorX, cursorY)); + } + break; + } + } + return true; +} + +void mouseDown(int theEvent) { + super.mouseDown(theEvent); + NSEvent nsEvent = new NSEvent(theEvent); + if (nsEvent.clickCount() !is 1) return; + NSPoint location = nsEvent.locationInWindow(); + NSPoint point = view.convertPoint_fromView_(location, null); + startX = (int)point.x; + startY = (int)point.y; + NSRect frame = view.frame(); + Event event = new Event (); + event.x = (int)frame.x; + event.y = (int)frame.y; + event.width = (int)frame.width; + event.height = (int)frame.height; + sendEvent (DWT.Selection, event); + if (isDisposed ()) return; + if (event.doit) { + lastX = event.x; + lastY = event.y; + dragging = true; + setLocation(event.x, event.y); + } +} + +void mouseDragged(int theEvent) { + super.mouseDragged(theEvent); + if (!dragging) return; + NSEvent nsEvent = new NSEvent(theEvent); + NSPoint location = nsEvent.locationInWindow(); + NSPoint point = view.convertPoint_fromView_(location, null); + NSRect frame = view.frame(); + NSRect parentFrame = parent.topView().frame(); + int newX = lastX, newY = lastY; + if ((style & DWT.VERTICAL) !is 0) { + newX = Math.min (Math.max (0, (int)(point.x + frame.x - startX)), (int)(parentFrame.width - frame.width)); + } else { + newY = Math.min (Math.max (0, (int)(point.y + frame.y - startY)), (int)(parentFrame.height - frame.height)); + } + if (newX is lastX && newY is lastY) return; + Event event = new Event (); + event.x = newX; + event.y = newY; + event.width = (int)frame.width; + event.height = (int)frame.height; + sendEvent (DWT.Selection, event); + if (isDisposed ()) return; + if (event.doit) { + lastX = event.x; + lastY = event.y; + setBounds (event.x, event.y, (int)frame.width, (int)frame.height); + } +} + +void mouseEntered(int theEvent) { + //TODO need to add tracking area + super.mouseEntered(theEvent); + sizeCursor.handle.set(); +} + +void mouseUp(int theEvent) { + super.mouseUp(theEvent); + if (!dragging) return; + dragging = false; + NSRect frame = view.frame(); + Event event = new Event (); + event.x = lastX; + event.y = lastY; + event.width = (int)frame.width; + event.height = (int)frame.height; + sendEvent (DWT.Selection, event); + if (isDisposed ()) return; + if (event.doit) { + setBounds (event.x, event.y, (int)frame.width, (int)frame.height); + } +} + +void releaseWidget () { + super.releaseWidget (); + if (sizeCursor !is null) sizeCursor.dispose (); + sizeCursor = null; +} + +/** + * Removes the listener from the collection of listeners who will + * be notified when the control is selected by the user. + * + * @param listener the listener which should no longer be notified + * + * @exception IllegalArgumentException <ul> + * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> + * </ul> + * @exception DWTException <ul> + * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> + * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> + * </ul> + * + * @see SelectionListener + * @see #addSelectionListener + */ +public void removeSelectionListener(SelectionListener listener) { + checkWidget(); + if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); + if (eventTable is null) return; + eventTable.unhook(DWT.Selection, listener); + eventTable.unhook(DWT.DefaultSelection,listener); +} + +int traversalCode (int key, NSEvent theEvent) { + return 0; +} + +}