Mercurial > projects > dwt-mac
diff dwt/widgets/Scrollable.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/Scrollable.d Sat Aug 09 17:00:02 2008 +0200 @@ -0,0 +1,312 @@ +/******************************************************************************* + * 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.Scrollable; + +import dwt.dwthelper.utils; + + +import dwt.DWT; +import dwt.DWTException; +import dwt.graphics.Rectangle; +import dwt.internal.cocoa.NSRect; +import dwt.internal.cocoa.NSScrollView; +import dwt.internal.cocoa.NSScroller; +import dwt.internal.cocoa.NSSize; +import dwt.internal.cocoa.NSView; +import dwt.internal.cocoa.OS; +import dwt.internal.cocoa.SWTScrollView; + +/** + * This class is the abstract superclass of all classes which + * represent controls that have standard scroll bars. + * <dl> + * <dt><b>Styles:</b></dt> + * <dd>H_SCROLL, V_SCROLL</dd> + * <dt><b>Events:</b> + * <dd>(none)</dd> + * </dl> + * <p> + * IMPORTANT: This class is intended to be subclassed <em>only</em> + * within the DWT implementation. + * </p> + */ +public abstract class Scrollable extends Control { + SWTScrollView scrollView; + ScrollBar horizontalBar, verticalBar; + +Scrollable () { + /* Do nothing */ +} + +/** + * 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#H_SCROLL + * @see DWT#V_SCROLL + * @see Widget#checkSubclass + * @see Widget#getStyle + */ +public Scrollable (Composite parent, int style) { + super (parent, style); +} + +/** + * Given a desired <em>client area</em> for the receiver + * (as described by the arguments), returns the bounding + * rectangle which would be required to produce that client + * area. + * <p> + * In other words, it returns a rectangle such that, if the + * receiver's bounds were set to that rectangle, the area + * of the receiver which is capable of displaying data + * (that is, not covered by the "trimmings") would be the + * rectangle described by the arguments (relative to the + * receiver's parent). + * </p> + * + * @param x the desired x coordinate of the client area + * @param y the desired y coordinate of the client area + * @param width the desired width of the client area + * @param height the desired height of the client area + * @return the required bounds to produce the given client area + * + * @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 #getClientArea + */ +public Rectangle computeTrim (int x, int y, int width, int height) { + checkWidget(); + if (scrollView !is null) { + NSSize size = new NSSize(); + size.width = width; + size.height = height; + int border = hasBorder() ? OS.NSBezelBorder : OS.NSNoBorder; + size = NSScrollView.frameSizeForContentSize(size, (style & DWT.H_SCROLL) !is 0, (style & DWT.V_SCROLL) !is 0, border); + width = (int)size.width; + height = (int)size.height; + NSRect frame = scrollView.contentView().frame(); + x -= frame.x; + y -= frame.y; + } + return new Rectangle (x, y, width, height); +} + +ScrollBar createScrollBar (int style) { + if (scrollView is null) return null; + ScrollBar bar = new ScrollBar (); + bar.parent = this; + bar.style = style; + bar.display = display; + NSScroller scroller; + int actionSelector; + if ((style & DWT.H_SCROLL) !is 0) { + scroller = scrollView.horizontalScroller(); + actionSelector = OS.sel_sendHorizontalSelection; + } else { + scroller = scrollView.verticalScroller(); + actionSelector = OS.sel_sendVerticalSelection; + } + bar.view = scroller; + bar.createJNIRef(); + scroller.setTag(bar.jniRef); + if ((state & CANVAS) is 0) { + bar.target = scroller.target(); + bar.actionSelector = scroller.action(); + } + scroller.setTarget(scrollView); + scroller.setAction(actionSelector); + return bar; +} + +void createWidget () { + super.createWidget (); + if ((style & DWT.H_SCROLL) !is 0) horizontalBar = createScrollBar (DWT.H_SCROLL); + if ((style & DWT.V_SCROLL) !is 0) verticalBar = createScrollBar (DWT.V_SCROLL); +} + +/** + * Returns a rectangle which describes the area of the + * receiver which is capable of displaying data (that is, + * not covered by the "trimmings"). + * + * @return the client area + * + * @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 #computeTrim + */ +public Rectangle getClientArea () { + checkWidget(); + if (scrollView !is null) { + NSSize size = scrollView.contentSize(); + return new Rectangle(0, 0, (int)size.width, (int)size.height); + } else { + NSRect rect = view.bounds(); + return new Rectangle(0, 0, (int)rect.width, (int)rect.height); + } +} + +/** + * Returns the receiver's horizontal scroll bar if it has + * one, and null if it does not. + * + * @return the horizontal scroll bar (or null) + * + * @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> + */ +public ScrollBar getHorizontalBar () { + checkWidget(); + return horizontalBar; +} + +/** + * Returns the receiver's vertical scroll bar if it has + * one, and null if it does not. + * + * @return the vertical scroll bar (or null) + * + * @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> + */ +public ScrollBar getVerticalBar () { + checkWidget(); + return verticalBar; +} + +bool hooksKeys () { + return hooks (DWT.KeyDown) || hooks (DWT.KeyUp) || hooks (DWT.Traverse); +} + + +void releaseHandle () { + super.releaseHandle (); + if (scrollView !is null) { + scrollView.setTag(-1); + scrollView.release(); + } + scrollView = null; +} + +void releaseChildren (bool destroy) { + if (horizontalBar !is null) { + horizontalBar.release (false); + horizontalBar = null; + } + if (verticalBar !is null) { + verticalBar.release (false); + verticalBar = null; + } + super.releaseChildren (destroy); +} + +void resizeClientArea () { +// if (scrolledHandle is 0) return; +// if ((state & CANVAS) is 0) return; +// int vWidth = 0, hHeight = 0; +// int [] outMetric = new int [1]; +// OS.GetThemeMetric (OS.kThemeMetricScrollBarWidth, outMetric); +// bool isVisibleHBar = horizontalBar !is null && horizontalBar.getVisible (); +// bool isVisibleVBar = verticalBar !is null && verticalBar.getVisible (); +// if (isVisibleHBar) hHeight = outMetric [0]; +// if (isVisibleVBar) vWidth = outMetric [0]; +// int width, height; +// CGRect rect = new CGRect (); +// OS.HIViewGetBounds (scrolledHandle, rect); +// width = (int) rect.width; +// height = (int) rect.height; +// Rect inset = inset (); +// width = Math.max (0, width - vWidth - inset.left - inset.right); +// height = Math.max (0, height - hHeight - inset.top - inset.bottom); +// setBounds (handle, inset.left, inset.top, width, height, true, true, false); +// if (isVisibleHBar) { +// setBounds (horizontalBar.handle, inset.left, inset.top + height, width, hHeight, true, true, false); +// } +// if (isVisibleVBar) { +// setBounds (verticalBar.handle, inset.left + width, inset.top, vWidth, height, true, true, false); +// } +} + +void sendHorizontalSelection () { + horizontalBar.sendSelection (); +} + +bool sendMouseWheel (short wheelAxis, int wheelDelta) { +// if ((state & CANVAS) !is 0) { +// ScrollBar bar = wheelAxis is OS.kEventMouseWheelAxisX ? horizontalBar : verticalBar; +// if (bar !is null && bar.getEnabled ()) { +// bar.setSelection (Math.max (0, bar.getSelection () - bar.getIncrement () * wheelDelta)); +// Event event = new Event (); +// event.detail = wheelDelta > 0 ? DWT.PAGE_UP : DWT.PAGE_DOWN; +// bar.sendEvent (DWT.Selection, event); +// return true; +// } +// } + return false; +} + +void sendVerticalSelection () { + verticalBar.sendSelection (); +} + +bool setScrollBarVisible (ScrollBar bar, bool visible) { + if (scrollView is null) return false; + if ((state & CANVAS) is 0) return false; + if (visible) { + if ((bar.state & HIDDEN) is 0) return false; + bar.state &= ~HIDDEN; + } else { + if ((bar.state & HIDDEN) !is 0) return false; + bar.state |= HIDDEN; + } + resizeClientArea (); +// setVisible (bar.handle, visible); + bar.sendEvent (visible ? DWT.Show : DWT.Hide); + sendEvent (DWT.Resize); + return true; +} + +NSView topView () { + if (scrollView !is null) return scrollView; + return super.topView (); +} +}