Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Scrollable.java')
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Scrollable.java427
1 files changed, 427 insertions, 0 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Scrollable.java b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Scrollable.java
new file mode 100644
index 0000000000..482e71323a
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/Scrollable.java
@@ -0,0 +1,427 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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
+ *******************************************************************************/
+package org.eclipse.swt.widgets;
+
+
+import org.eclipse.swt.internal.carbon.OS;
+import org.eclipse.swt.internal.carbon.CGRect;
+import org.eclipse.swt.internal.carbon.Rect;
+import org.eclipse.swt.internal.carbon.ControlKind;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+/**
+ * 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 SWT implementation.
+ * </p>
+ *
+ * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public abstract class Scrollable extends Control {
+ int scrolledHandle;
+ 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>SWT</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>SWT</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 SWTException <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 SWT#H_SCROLL
+ * @see SWT#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 SWTException <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();
+ int [] outMetric = new int [1];
+ OS.GetThemeMetric (OS.kThemeMetricScrollBarWidth, outMetric);
+ if (horizontalBar != null) height += outMetric [0];
+ if (verticalBar != null) width += outMetric [0];
+ Rect inset = inset ();
+ x -= inset.left;
+ y -= inset.top;
+ width += inset.left + inset.right;
+ height += inset.top + inset.bottom;
+ return new Rectangle (x, y, width, height);
+}
+
+ScrollBar createScrollBar (int style) {
+ return new ScrollBar (this, style);
+}
+
+ScrollBar createStandardBar (int style) {
+ int barHandle = findStandardBar (style);
+ if (barHandle == 0) return null;
+ ScrollBar bar = new ScrollBar ();
+ bar.parent = this;
+ bar.style = style;
+ bar.display = display;
+ bar.handle = barHandle;
+ bar.register ();
+ bar.hookEvents ();
+ return bar;
+}
+
+void createWidget () {
+ super.createWidget ();
+ if ((style & SWT.H_SCROLL) != 0) horizontalBar = createScrollBar (SWT.H_SCROLL);
+ if ((style & SWT.V_SCROLL) != 0) verticalBar = createScrollBar (SWT.V_SCROLL);
+}
+
+void deregister () {
+ super.deregister ();
+ if (scrolledHandle != 0) display.removeWidget (scrolledHandle);
+}
+
+void destroyScrollBar (ScrollBar bar) {
+ setScrollBarVisible (bar, false);
+ bar.destroyHandle ();
+}
+
+int findStandardBar (int style) {
+ int parentHandle = scrolledHandle != 0 ? scrolledHandle : handle;
+ short [] count = new short [1];
+ OS.CountSubControls (parentHandle, count);
+ if (count [0] == 0) return 0;
+ int barHandle = 0;
+ int [] outMetric = new int [1];
+ OS.GetThemeMetric (OS.kThemeMetricScrollBarWidth, outMetric);
+ int [] outControl = new int [1];
+ ControlKind kind = new ControlKind ();
+ int [] property = new int [1];
+ for (int i = 0; i < count [0]; i++) {
+ OS.GetIndexedSubControl (parentHandle, (short) (i + 1), outControl);
+ OS.GetControlKind (outControl [0], kind);
+ if (kind.kind == OS.kControlKindScrollBar) {
+ property [0] = 0;
+ OS.GetControlProperty (outControl [0], Display.SWT0, Display.SWT0, 4, null, property);
+ if (property [0] == 0) {
+ Point point = getControlSize (outControl [0]);
+ if ((style & SWT.H_SCROLL) != 0) {
+ if (point.y == outMetric [0]) barHandle = outControl [0];
+ } else {
+ if (point.x == outMetric [0]) barHandle = outControl [0];
+ }
+ }
+ }
+ }
+ return barHandle;
+}
+
+public int getBorderWidth () {
+ checkWidget();
+ if ((state & CANVAS) != 0 && hasBorder ()) {
+ int [] outMetric = new int [1];
+ OS.GetThemeMetric (OS.kThemeMetricEditTextFrameOutset, outMetric);
+ return outMetric [0];
+ }
+ return 0;
+}
+
+/**
+ * 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 SWTException <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();
+ Rect rect = new Rect ();
+ OS.GetControlBounds (handle, rect);
+ return new Rectangle (0, 0, rect.right - rect.left, rect.bottom - rect.top);
+}
+
+/**
+ * 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 SWTException <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 SWTException <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;
+}
+
+void hookEvents () {
+ super.hookEvents ();
+ if ((state & CANVAS) != 0 && scrolledHandle != 0) {
+ int controlProc = display.controlProc;
+ int [] mask = new int [] {
+ OS.kEventClassControl, OS.kEventControlDraw,
+ };
+ int controlTarget = OS.GetControlEventTarget (scrolledHandle);
+ OS.InstallEventHandler (controlTarget, controlProc, mask.length / 2, mask, scrolledHandle, null);
+ }
+}
+
+boolean hooksKeys () {
+ return hooks (SWT.KeyDown) || hooks (SWT.KeyUp) || hooks (SWT.Traverse);
+}
+
+Rect inset () {
+ if ((state & CANVAS) != 0) {
+ Rect rect = new Rect ();
+ int [] outMetric = new int [1];
+ if (drawFocusRing () && (style & SWT.NO_FOCUS) == 0 && hooksKeys ()) {
+ OS.GetThemeMetric (OS.kThemeMetricFocusRectOutset, outMetric);
+ rect.left += outMetric [0];
+ rect.top += outMetric [0];
+ rect.right += outMetric [0];
+ rect.bottom += outMetric [0];
+ }
+ if (hasBorder ()) {
+ OS.GetThemeMetric (OS.kThemeMetricEditTextFrameOutset, outMetric);
+ rect.left += outMetric [0];
+ rect.top += outMetric [0];
+ rect.right += outMetric [0];
+ rect.bottom += outMetric [0];
+ }
+ return rect;
+ }
+ return EMPTY_RECT;
+}
+
+boolean isTrimHandle (int trimHandle) {
+ if (horizontalBar != null && horizontalBar.handle == trimHandle) return true;
+ if (verticalBar != null && verticalBar.handle == trimHandle) return true;
+ return trimHandle == scrolledHandle;
+}
+
+int kEventMouseWheelMoved (int nextHandler, int theEvent, int userData) {
+ int vPosition = verticalBar == null ? 0 : verticalBar.getSelection ();
+ int hPosition = horizontalBar == null ? 0 : horizontalBar.getSelection ();
+ int result = super.kEventMouseWheelMoved (nextHandler, theEvent, userData);
+ boolean redraw = false;
+ if (verticalBar != null) {
+ int position = verticalBar.getSelection ();
+ if (position != vPosition) {
+ Event event = new Event ();
+ event.detail = position < vPosition ? SWT.PAGE_UP : SWT.PAGE_DOWN;
+ verticalBar.sendEvent (SWT.Selection, event);
+ redraw = true;
+ }
+ }
+ if (horizontalBar != null) {
+ int position = horizontalBar.getSelection ();
+ if (position != hPosition) {
+ Event event = new Event ();
+ event.detail = position < hPosition ? SWT.PAGE_UP : SWT.PAGE_DOWN;
+ horizontalBar.sendEvent (SWT.Selection, event);
+ redraw = true;
+ }
+ }
+ if (redraw) redrawBackgroundImage ();
+ return result;
+}
+
+void redrawBackgroundImage () {
+ if (scrolledHandle == 0) {
+ Control control = findBackgroundControl();
+ if (control != null && control.backgroundImage != null) {
+ redrawWidget (handle, false);
+ }
+ }
+}
+
+void register () {
+ super.register ();
+ if (scrolledHandle != 0) display.addWidget (scrolledHandle, this);
+}
+
+void releaseHandle () {
+ super.releaseHandle ();
+ scrolledHandle = 0;
+}
+
+void releaseChildren (boolean destroy) {
+ if (horizontalBar != null) {
+ horizontalBar.release (false);
+ horizontalBar = null;
+ }
+ if (verticalBar != null) {
+ verticalBar.release (false);
+ verticalBar = null;
+ }
+ super.releaseChildren (destroy);
+}
+
+void resetVisibleRegion (int control) {
+ if (verticalBar != null) verticalBar.resetVisibleRegion (control);
+ if (horizontalBar != null) horizontalBar.resetVisibleRegion (control);
+ super.resetVisibleRegion (control);
+}
+
+void resizeClientArea () {
+ if (scrolledHandle == 0) return;
+ if ((state & CANVAS) == 0) return;
+ int vWidth = 0, hHeight = 0;
+ int [] outMetric = new int [1];
+ OS.GetThemeMetric (OS.kThemeMetricScrollBarWidth, outMetric);
+ boolean isVisibleHBar = horizontalBar != null && horizontalBar.getVisible ();
+ boolean isVisibleVBar = verticalBar != 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);
+ }
+}
+
+boolean sendMouseWheel (short wheelAxis, int wheelDelta) {
+ if ((state & CANVAS) != 0) {
+ ScrollBar bar = wheelAxis == OS.kEventMouseWheelAxisX ? horizontalBar : verticalBar;
+ if (bar != null && bar.getEnabled ()) {
+ bar.setSelection (Math.max (0, bar.getSelection () - bar.getIncrement () * wheelDelta));
+ Event event = new Event ();
+ event.detail = wheelDelta > 0 ? SWT.PAGE_UP : SWT.PAGE_DOWN;
+ bar.sendEvent (SWT.Selection, event);
+ return true;
+ }
+ }
+ return false;
+}
+
+int setBounds (int x, int y, int width, int height, boolean move, boolean resize, boolean events) {
+ int result = super.setBounds(x, y, width, height, move, resize, false);
+ if ((result & MOVED) != 0) {
+ if (events) sendEvent (SWT.Move);
+ }
+ if ((result & RESIZED) != 0) {
+ resizeClientArea ();
+ if (events) sendEvent (SWT.Resize);
+ }
+ return result;
+}
+
+boolean setScrollBarVisible (ScrollBar bar, boolean visible) {
+ if (scrolledHandle == 0) return false;
+ if ((state & CANVAS) == 0) return false;
+ resizeClientArea ();
+ setVisible (bar.handle, visible);
+ return true;
+}
+
+void setZOrder () {
+ super.setZOrder ();
+ if (scrolledHandle != 0) OS.HIViewAddSubview (scrolledHandle, handle);
+}
+
+int topHandle () {
+ if (scrolledHandle != 0) return scrolledHandle;
+ return handle;
+}
+
+}

Back to the top