Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[platform-swt-dev] Drop-down toolitem improvements...

Hi,

This is still work in progress, but I wanted to get it out and see what you think - is it feasible for this work to enter the SWT project?

Thanks,
Nikolay
Index: src/org/eclipse/jface/action/ActionContributionItem.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jface/src/org/eclipse/jface/action/ActionContributionItem.java,v
retrieving revision 1.79
diff -u -r1.79 ActionContributionItem.java
--- src/org/eclipse/jface/action/ActionContributionItem.java	30 Apr 2007 15:33:52 -0000	1.79
+++ src/org/eclipse/jface/action/ActionContributionItem.java	15 Jun 2007 06:21:33 -0000
@@ -25,8 +25,6 @@
 import org.eclipse.jface.util.PropertyChangeEvent;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.Point;
-import org.eclipse.swt.graphics.Rectangle;
 import org.eclipse.swt.widgets.Button;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Display;
@@ -516,14 +514,15 @@
 						// dummy.dispose();
 						if (mc != null) {
 							Menu m = mc.getMenu(ti.getParent());
+							ti.setDropDownMenu(m);
 							if (m != null) {
 								// position the menu below the drop down item
-								Rectangle b = ti.getBounds();
-								Point p = ti.getParent().toDisplay(
-										new Point(b.x, b.y + b.height));
-								m.setLocation(p.x, p.y); // waiting for SWT
+								// Rectangle b = ti.getBounds();
+								// Point p = ti.getParent().toDisplay(
+								// 		new Point(b.x, b.y + b.height));
+								// m.setLocation(p.x, p.y); // waiting for SWT
 															// 0.42
-								m.setVisible(true);
+								// m.setVisible(true);
 								return; // we don't fire the action
 							}
 						}
Index: Eclipse SWT PI/win32/library/os_structs.h
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT PI/win32/library/os_structs.h,v
retrieving revision 1.46
diff -u -r1.46 os_structs.h
--- Eclipse SWT PI/win32/library/os_structs.h	24 Apr 2007 22:42:37 -0000	1.46
+++ Eclipse SWT PI/win32/library/os_structs.h	15 Jun 2007 08:40:18 -0000
@@ -1427,6 +1427,18 @@
 #define TOOLINFO_sizeof() 0
 #endif
 
+#ifndef NO_TPMPARAMS
+void cacheTPMPARAMSFields(JNIEnv *env, jobject lpObject);
+TPMPARAMS *getTPMPARAMSFields(JNIEnv *env, jobject lpObject, TPMPARAMS *lpStruct);
+void setTPMPARAMSFields(JNIEnv *env, jobject lpObject, TPMPARAMS *lpStruct);
+#define TPMPARAMS_sizeof() sizeof(TPMPARAMS)
+#else
+#define cacheTPMPARAMSFields(a,b)
+#define getTPMPARAMSFields(a,b,c) NULL
+#define setTPMPARAMSFields(a,b,c)
+#define TPMPARAMS_sizeof() 0
+#endif
+
 #ifndef NO_TRACKMOUSEEVENT
 void cacheTRACKMOUSEEVENTFields(JNIEnv *env, jobject lpObject);
 TRACKMOUSEEVENT *getTRACKMOUSEEVENTFields(JNIEnv *env, jobject lpObject, TRACKMOUSEEVENT *lpStruct);
Index: Eclipse SWT PI/win32/library/os_stats.h
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.h,v
retrieving revision 1.88
diff -u -r1.88 os_stats.h
--- Eclipse SWT PI/win32/library/os_stats.h	15 May 2007 14:28:50 -0000	1.88
+++ Eclipse SWT PI/win32/library/os_stats.h	15 Jun 2007 08:40:08 -0000
@@ -866,6 +866,7 @@
 	ToUnicode_FUNC,
 	TrackMouseEvent_FUNC,
 	TrackPopupMenu_FUNC,
+	TrackPopupMenuEx_FUNC,
 	TranslateAcceleratorA_FUNC,
 	TranslateAcceleratorW_FUNC,
 	TranslateCharsetInfo_FUNC,
Index: Eclipse SWT PI/win32/library/os_structs.c
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT PI/win32/library/os_structs.c,v
retrieving revision 1.54
diff -u -r1.54 os_structs.c
--- Eclipse SWT PI/win32/library/os_structs.c	24 Apr 2007 22:42:37 -0000	1.54
+++ Eclipse SWT PI/win32/library/os_structs.c	15 Jun 2007 08:40:16 -0000
@@ -6523,6 +6523,49 @@
 }
 #endif
 
+#ifndef NO_TPMPARAMS
+typedef struct TPMPARAMS_FID_CACHE {
+	int cached;
+	jclass clazz;
+	jfieldID cbSize, left, top, right, bottom;
+} TPMPARAMS_FID_CACHE;
+
+TPMPARAMS_FID_CACHE TPMPARAMSFc;
+
+void cacheTPMPARAMSFields(JNIEnv *env, jobject lpObject)
+{
+	if (TPMPARAMSFc.cached) return;
+	TPMPARAMSFc.clazz = (*env)->GetObjectClass(env, lpObject);
+	TPMPARAMSFc.cbSize = (*env)->GetFieldID(env, TPMPARAMSFc.clazz, "cbSize", "I");
+	TPMPARAMSFc.left = (*env)->GetFieldID(env, TPMPARAMSFc.clazz, "left", "I");
+	TPMPARAMSFc.top = (*env)->GetFieldID(env, TPMPARAMSFc.clazz, "top", "I");
+	TPMPARAMSFc.right = (*env)->GetFieldID(env, TPMPARAMSFc.clazz, "right", "I");
+	TPMPARAMSFc.bottom = (*env)->GetFieldID(env, TPMPARAMSFc.clazz, "bottom", "I");
+	TPMPARAMSFc.cached = 1;
+}
+
+TPMPARAMS *getTPMPARAMSFields(JNIEnv *env, jobject lpObject, TPMPARAMS *lpStruct)
+{
+	if (!TPMPARAMSFc.cached) cacheTPMPARAMSFields(env, lpObject);
+	lpStruct->cbSize = (*env)->GetIntField(env, lpObject, TPMPARAMSFc.cbSize);
+	lpStruct->rcExclude.left = (*env)->GetIntField(env, lpObject, TPMPARAMSFc.left);
+	lpStruct->rcExclude.top = (*env)->GetIntField(env, lpObject, TPMPARAMSFc.top);
+	lpStruct->rcExclude.right = (*env)->GetIntField(env, lpObject, TPMPARAMSFc.right);
+	lpStruct->rcExclude.bottom = (*env)->GetIntField(env, lpObject, TPMPARAMSFc.bottom);
+	return lpStruct;
+}
+
+void setTPMPARAMSFields(JNIEnv *env, jobject lpObject, TPMPARAMS *lpStruct)
+{
+	if (!TPMPARAMSFc.cached) cacheTPMPARAMSFields(env, lpObject);
+	(*env)->SetIntField(env, lpObject, TPMPARAMSFc.cbSize, (jint)lpStruct->cbSize);
+	(*env)->SetIntField(env, lpObject, TPMPARAMSFc.left, (jint)lpStruct->rcExclude.left);
+	(*env)->SetIntField(env, lpObject, TPMPARAMSFc.top, (jint)lpStruct->rcExclude.top);
+	(*env)->SetIntField(env, lpObject, TPMPARAMSFc.right, (jint)lpStruct->rcExclude.right);
+	(*env)->SetIntField(env, lpObject, TPMPARAMSFc.bottom, (jint)lpStruct->rcExclude.bottom);
+}
+#endif
+
 #ifndef NO_TRACKMOUSEEVENT
 typedef struct TRACKMOUSEEVENT_FID_CACHE {
 	int cached;
Index: Eclipse SWT PI/win32/library/os_stats.c
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT PI/win32/library/os_stats.c,v
retrieving revision 1.88
diff -u -r1.88 os_stats.c
--- Eclipse SWT PI/win32/library/os_stats.c	15 May 2007 14:28:50 -0000	1.88
+++ Eclipse SWT PI/win32/library/os_stats.c	15 Jun 2007 08:40:07 -0000
@@ -14,8 +14,8 @@
 
 #ifdef NATIVE_STATS
 
-int OS_nativeFunctionCount = 873;
-int OS_nativeFunctionCallCount[873];
+int OS_nativeFunctionCount = 874;
+int OS_nativeFunctionCallCount[874];
 char * OS_nativeFunctionNames[] = {
 	"ACCEL_1sizeof",
 	"ACTCTX_1sizeof",
@@ -858,6 +858,7 @@
 	"ToUnicode",
 	"TrackMouseEvent",
 	"TrackPopupMenu",
+	"TrackPopupMenuEx",
 	"TranslateAcceleratorA",
 	"TranslateAcceleratorW",
 	"TranslateCharsetInfo",
Index: Eclipse SWT PI/win32/library/os.c
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT PI/win32/library/os.c,v
retrieving revision 1.128
diff -u -r1.128 os.c
--- Eclipse SWT PI/win32/library/os.c	15 May 2007 14:28:50 -0000	1.128
+++ Eclipse SWT PI/win32/library/os.c	15 Jun 2007 08:40:07 -0000
@@ -13396,6 +13396,18 @@
 }
 #endif
 
+#ifndef NO_TPMPARAMS_1sizeof
+JNIEXPORT jint JNICALL OS_NATIVE(TPMPARAMS_1sizeof)
+	(JNIEnv *env, jclass that)
+{
+	jint rc = 0;
+	OS_NATIVE_ENTER(env, that, TPMPARAMS_1sizeof_FUNC);
+	rc = (jint)TPMPARAMS_sizeof();
+	OS_NATIVE_EXIT(env, that, TPMPARAMS_1sizeof_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO_TRACKMOUSEEVENT_1sizeof
 JNIEXPORT jint JNICALL OS_NATIVE(TRACKMOUSEEVENT_1sizeof)
 	(JNIEnv *env, jclass that)
@@ -13550,6 +13562,22 @@
 }
 #endif
 
+#ifndef NO_TrackPopupMenuEx
+JNIEXPORT jboolean JNICALL OS_NATIVE(TrackPopupMenuEx)
+	(JNIEnv *env, jclass that, jint arg0, jint arg1, jint arg2, jint arg3, jint arg4, jobject arg5)
+{
+	TPMPARAMS _arg5, *lparg5=NULL;
+	jboolean rc = 0;
+	OS_NATIVE_ENTER(env, that, TrackPopupMenuEx_FUNC);
+	if (arg5) if ((lparg5 = getTPMPARAMSFields(env, arg5, &_arg5)) == NULL) goto fail;
+	rc = (jboolean)TrackPopupMenuEx(arg0, arg1, arg2, arg3, arg4, lparg5);
+fail:
+	if (arg5 && lparg5) setTPMPARAMSFields(env, arg5, lparg5);
+	OS_NATIVE_EXIT(env, that, TrackPopupMenuEx_FUNC);
+	return rc;
+}
+#endif
+
 #ifndef NO_TranslateAcceleratorA
 JNIEXPORT jint JNICALL OS_NATIVE(TranslateAcceleratorA)
 	(JNIEnv *env, jclass that, jint arg0, jint arg1, jobject arg2)
Index: Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java,v
retrieving revision 1.106
diff -u -r1.106 ToolItem.java
--- Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java	31 May 2007 22:03:48 -0000	1.106
+++ Eclipse SWT/gtk/org/eclipse/swt/widgets/ToolItem.java	15 Jun 2007 08:40:24 -0000
@@ -38,6 +38,7 @@
 	ToolBar parent;
 	Control control;
 	Image hotImage, disabledImage;
+	Menu dropDownMenu;
 	String toolTipText;
 	boolean drawHotImage;
 
@@ -360,6 +361,24 @@
 }
 
 /**
+ * Returns the receiver's drop-down menu if it has one, or null 
+ * if it does not.
+ * <p>
+ * The drop-down menu is activated when the arrow of an {@link SWT#DROP_DOWN}-styled receiver is pressed.
+ * </p>
+ * 
+ * @return the receiver's drop-down menu
+ * @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 Menu getDropDownMenu () {
+	checkWidget();
+	return dropDownMenu;
+}
+
+/**
  * Returns <code>true</code> if the receiver is enabled, and
  * <code>false</code> otherwise. A disabled control is typically
  * not selectable from the user interface and draws with an
@@ -534,7 +553,14 @@
 			selectRadio ();
 		}
 	}
-	postEvent (SWT.Selection, event);
+	if (event.detail == SWT.ARROW) {
+		sendEvent (SWT.Selection, event);
+		if (event.doit) {
+			ToolItemHelper.showDropDownMenu (this);
+		}
+	} else {
+		postEvent (SWT.Selection, event);
+	}
 	return 0;
 }
 
@@ -788,6 +814,30 @@
 }
 
 /**
+ * Sets the receiver's drop-down menu to the argument, which may be 
+ * null indicating that no drop-down menu should be displayed.
+ * <p>
+ * If this property is null a drop-down menu can still be displayed manually by adding a
+ * {@link SelectionListener} to the receiver and handling{@link SWT#ARROW} events.
+ * <p>
+ * The drop-down menu is activated when the arrow of an {@link SWT#DROP_DOWN}-styled receiver is pressed.
+ * Attempts to set a drop-dwn menu for a receiver that does not have the {@link SWT#DROP_DOWN}
+ * style are ignored.
+ * </p>
+ * 
+ * @param menu the drop-down menu to be displayed when the receiver's arrow is pressed
+ * @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 void setDropDownMenu (Menu menu) {
+	checkWidget();
+	if ((style & SWT.DROP_DOWN) == 0) return;
+	dropDownMenu = menu;
+}
+
+/**
  * Enables the receiver if the argument is <code>true</code>,
  * and disables it otherwise.
  * <p>
Index: Eclipse SWT/photon/org/eclipse/swt/widgets/ToolItem.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT/photon/org/eclipse/swt/widgets/ToolItem.java,v
retrieving revision 1.47
diff -u -r1.47 ToolItem.java
--- Eclipse SWT/photon/org/eclipse/swt/widgets/ToolItem.java	31 May 2007 22:04:10 -0000	1.47
+++ Eclipse SWT/photon/org/eclipse/swt/widgets/ToolItem.java	15 Jun 2007 08:40:26 -0000
@@ -39,6 +39,7 @@
 	String toolTipText;
 	int toolTipHandle;
 	Image hotImage, disabledImage;
+	Menu dropDownMenu;
 	int button, arrow;
 
 /**
@@ -349,6 +350,24 @@
 }
 
 /**
+ * Returns the receiver's drop-down menu if it has one, or null 
+ * if it does not.
+ * <p>
+ * The drop-down menu is activated when the arrow of an {@link SWT#DROP_DOWN}-styled receiver is pressed.
+ * </p>
+ * 
+ * @return the receiver's drop-down menu
+ * @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 Menu getDropDownMenu () {
+	checkWidget();
+	return dropDownMenu;
+}
+
+/**
  * Returns <code>true</code> if the receiver is enabled, and
  * <code>false</code> otherwise. A disabled control is typically
  * not selectable from the user interface and draws with an
@@ -534,14 +553,18 @@
 		OS.PtWidgetArea (topHandle, area);
 		event.x = area.pos_x;
 		event.y = area.pos_y + area.size_h;
+		sendEvent (SWT.Selection, event);
+		if (event.doit) {
+			ToolItemHelper.showDropDownMenu(this);
+		}
 	} else {
 		if ((style & SWT.RADIO) != 0) {
 			if ((parent.getStyle () & SWT.NO_RADIO_GROUP) == 0) {
 				selectRadio ();
 			}
 		}
+		postEvent (SWT.Selection, event);
 	}
-	postEvent (SWT.Selection, event);
 	return OS.Pt_CONTINUE;
 }
 
@@ -683,6 +706,30 @@
 }
 
 /**
+ * Sets the receiver's drop-down menu to the argument, which may be 
+ * null indicating that no drop-down menu should be displayed.
+ * <p>
+ * If this property is null a drop-down menu can still be displayed manually by adding a
+ * {@link SelectionListener} to the receiver and handling{@link SWT#ARROW} events.
+ * <p>
+ * The drop-down menu is activated when the arrow of an {@link SWT#DROP_DOWN}-styled receiver is pressed.
+ * Attempts to set a drop-dwn menu for a receiver that does not have the {@link SWT#DROP_DOWN}
+ * style are ignored.
+ * </p>
+ * 
+ * @param menu the drop-down menu to be displayed when the receiver's arrow is pressed
+ * @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 void setDropDownMenu (Menu menu) {
+	checkWidget();
+	if ((style & SWT.DROP_DOWN) == 0) return;
+	dropDownMenu = menu;
+}
+
+/**
  * Enables the receiver if the argument is <code>true</code>,
  * and disables it otherwise.
  * <p>
Index: Eclipse SWT/motif/org/eclipse/swt/widgets/ToolItem.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT/motif/org/eclipse/swt/widgets/ToolItem.java,v
retrieving revision 1.89
diff -u -r1.89 ToolItem.java
--- Eclipse SWT/motif/org/eclipse/swt/widgets/ToolItem.java	31 May 2007 22:03:50 -0000	1.89
+++ Eclipse SWT/motif/org/eclipse/swt/widgets/ToolItem.java	15 Jun 2007 08:40:25 -0000
@@ -11,6 +11,7 @@
 package org.eclipse.swt.widgets;
 
 
+import org.eclipse.swt.internal.ToolItemHelper;
 import org.eclipse.swt.internal.motif.*;
 import org.eclipse.swt.*;
 import org.eclipse.swt.graphics.*;
@@ -35,6 +36,7 @@
 public class ToolItem extends Item {
 	ToolBar parent;
 	Image hotImage, disabledImage;
+	Menu dropDownMenu;
 	String toolTipText;
 	Control control;
 	int width = DEFAULT_SEPARATOR_WIDTH;
@@ -216,7 +218,14 @@
 		}
 	}
 	if (state != 0) setInputState (event, state);
-	postEvent (SWT.Selection, event);
+	if (event.detail == SWT.ARROW) {
+		sendEvent (SWT.Selection, event);
+		if (event.doit) {
+			ToolItemHelper.showDropDownMenu (this);
+		}
+	} else {
+		postEvent (SWT.Selection, event);
+	}
 }
 
 Point computeSize (GC gc) {
@@ -360,6 +369,23 @@
 	return disabledImage;
 }
 /**
+ * Returns the receiver's drop-down menu if it has one, or null 
+ * if it does not.
+ * <p>
+ * The drop-down menu is activated when the arrow of an {@link SWT#DROP_DOWN}-styled receiver is pressed.
+ * </p>
+ * 
+ * @return the receiver's drop-down menu
+ * @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 Menu getDropDownMenu () {
+	checkWidget();
+	return dropDownMenu;
+}
+/**
  * Returns <code>true</code> if the receiver is enabled, and
  * <code>false</code> otherwise. A disabled control is typically
  * not selectable from the user interface and draws with an
@@ -702,6 +728,29 @@
 	disabledImage = image;
 	if (!getEnabled ()) redraw ();
 }
+/**
+ * Sets the receiver's drop-down menu to the argument, which may be 
+ * null indicating that no drop-down menu should be displayed.
+ * <p>
+ * If this property is null a drop-down menu can still be displayed manually by adding a
+ * {@link SelectionListener} to the receiver and handling{@link SWT#ARROW} events.
+ * <p>
+ * The drop-down menu is activated when the arrow of an {@link SWT#DROP_DOWN}-styled receiver is pressed.
+ * Attempts to set a drop-dwn menu for a receiver that does not have the {@link SWT#DROP_DOWN}
+ * style are ignored.
+ * </p>
+ * 
+ * @param menu the drop-down menu to be displayed when the receiver's arrow is pressed
+ * @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 void setDropDownMenu (Menu menu) {
+	checkWidget();
+	if ((style & SWT.DROP_DOWN) == 0) return;
+	dropDownMenu = menu;
+}
 boolean setFocus () {
 	if ((style & SWT.SEPARATOR) != 0) return false;
 	return XmProcessTraversal (handle, OS.XmTRAVERSE_CURRENT);
Index: Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java,v
retrieving revision 1.343
diff -u -r1.343 OS.java
--- Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java	31 May 2007 22:03:57 -0000	1.343
+++ Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java	15 Jun 2007 08:40:23 -0000
@@ -1618,6 +1618,7 @@
 	public static final int TPM_LEFTBUTTON = 0x0;
 	public static final int TPM_RIGHTBUTTON = 0x2;
 	public static final int TPM_RIGHTALIGN = 0x8;
+	public static final int TPM_VERTICAL = 0x40;
 	public static final String TRACKBAR_CLASS = "msctls_trackbar32"; //$NON-NLS-1$
 	public static final int TRANSPARENT = 0x1;
 	public static final int TREIS_DISABLED = 4;
@@ -2138,6 +2139,7 @@
 public static final native int TEXTMETRICA_sizeof ();
 public static final native int TEXTMETRICW_sizeof ();
 public static final native int TOOLINFO_sizeof ();
+public static final native int TPMPARAMS_sizeof ();
 public static final native int TRACKMOUSEEVENT_sizeof ();
 public static final native int TRIVERTEX_sizeof ();
 public static final native int TVHITTESTINFO_sizeof ();
@@ -3848,6 +3850,7 @@
 public static final native int ToUnicode (int wVirtKey, int wScanCode, byte [] lpKeyState, char [] pwszBuff, int cchBuff, int wFlags);
 public static final native boolean TrackMouseEvent (TRACKMOUSEEVENT lpEventTrack);
 public static final native boolean TrackPopupMenu (int /*long*/ hMenu, int uFlags, int x, int y, int nReserved, int /*long*/ hWnd, RECT prcRect);
+public static final native boolean TrackPopupMenuEx (int /*long*/ hMenu, int uFlags, int x, int y, int /*long*/ hWnd, TPMPARAMS lptpm);
 public static final native int TranslateAcceleratorW (int /*long*/ hWnd, int /*long*/ hAccTable, MSG lpMsg);
 public static final native int TranslateAcceleratorA (int /*long*/ hWnd, int /*long*/ hAccTable, MSG lpMsg);
 public static final native boolean TranslateCharsetInfo (int /*long*/ lpSrc, int [] lpCs, int dwFlags);
Index: Eclipse SWT/win32/org/eclipse/swt/widgets/ToolItem.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolItem.java,v
retrieving revision 1.69
diff -u -r1.69 ToolItem.java
--- Eclipse SWT/win32/org/eclipse/swt/widgets/ToolItem.java	31 May 2007 22:04:12 -0000	1.69
+++ Eclipse SWT/win32/org/eclipse/swt/widgets/ToolItem.java	15 Jun 2007 08:40:29 -0000
@@ -39,6 +39,7 @@
 	String toolTipText;
 	Image disabledImage, hotImage;
 	Image disabledImage2;
+	Menu dropDownMenu;
 	int id;
 
 /**
@@ -254,6 +255,24 @@
 }
 
 /**
+ * Returns the receiver's drop-down menu if it has one, or null 
+ * if it does not.
+ * <p>
+ * The drop-down menu is activated when the arrow of an {@link SWT#DROP_DOWN}-styled receiver is pressed.
+ * </p>
+ * 
+ * @return the receiver's drop-down menu
+ * @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 Menu getDropDownMenu () {
+	checkWidget();
+	return dropDownMenu;
+}
+
+/**
  * Returns <code>true</code> if the receiver is enabled, and
  * <code>false</code> otherwise. A disabled control is typically
  * not selectable from the user interface and draws with an
@@ -638,6 +657,30 @@
 }
 
 /**
+ * Sets the receiver's drop-down menu to the argument, which may be 
+ * null indicating that no drop-down menu should be displayed.
+ * <p>
+ * If this property is null a drop-down menu can still be displayed manually by adding a
+ * {@link SelectionListener} to the receiver and handling{@link SWT#ARROW} events.
+ * <p>
+ * The drop-down menu is activated when the arrow of an {@link SWT#DROP_DOWN}-styled receiver is pressed.
+ * Attempts to set a drop-dwn menu for a receiver that does not have the {@link SWT#DROP_DOWN}
+ * style are ignored.
+ * </p>
+ * 
+ * @param menu the drop-down menu to be displayed when the receiver's arrow is pressed
+ * @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 void setDropDownMenu (Menu menu) {
+	checkWidget();
+	if ((style & SWT.DROP_DOWN) == 0) return;
+	dropDownMenu = menu;
+}
+
+/**
  * Sets the receiver's hot image to the argument, which may be
  * null indicating that no hot image should be displayed.
  * <p>
Index: Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java,v
retrieving revision 1.116
diff -u -r1.116 ToolBar.java
--- Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java	31 May 2007 22:04:16 -0000	1.116
+++ Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java	15 Jun 2007 08:40:28 -0000
@@ -1306,7 +1306,15 @@
 				OS.SendMessage (handle, OS.TB_GETITEMRECT, index, rect);
 				event.x = rect.left;
 				event.y = rect.bottom;
-				child.postEvent (SWT.Selection, event);
+				child.sendEvent (SWT.Selection, event);
+				if (event.doit) {
+					Menu dropDownMenu = child.dropDownMenu;
+					if (dropDownMenu != null) {
+						OS.MapWindowPoints(handle, 0, rect, 2);
+						dropDownMenu.setLocation (rect.left, rect.bottom);
+						dropDownMenu._setVisible (true, rect, OS.TPM_VERTICAL);
+					}
+				}
 			}
 			break;
 		case OS.NM_CUSTOMDRAW:
Index: Eclipse SWT/win32/org/eclipse/swt/widgets/Menu.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Menu.java,v
retrieving revision 1.109
diff -u -r1.109 Menu.java
--- Eclipse SWT/win32/org/eclipse/swt/widgets/Menu.java	31 May 2007 22:04:12 -0000	1.109
+++ Eclipse SWT/win32/org/eclipse/swt/widgets/Menu.java	15 Jun 2007 08:40:27 -0000
@@ -196,6 +196,10 @@
 }
 
 void _setVisible (boolean visible) {
+	_setVisible(visible, null, 0);
+}
+
+void _setVisible (boolean visible, RECT excludeRect, int extraFlags) {
 	if ((style & (SWT.BAR | SWT.DROP_DOWN)) != 0) return;
 	int hwndParent = parent.handle;
 	if (visible) {
@@ -206,6 +210,7 @@
 			flags &= ~OS.TPM_RIGHTALIGN;
 			if ((style & SWT.LEFT_TO_RIGHT) != 0) flags |= OS.TPM_RIGHTALIGN;
 		}
+		flags |= extraFlags;
 		int nX = x, nY = y;
 		if (!hasLocation) {
 			int pos = OS.GetMessagePos ();
@@ -225,7 +230,18 @@
 		* case when TrackPopupMenu() fails and the number of items in
 		* the menu is zero and issue a fake WM_MENUSELECT.
 		*/
-		boolean success = OS.TrackPopupMenu (handle, flags, nX, nY, 0, hwndParent, null);
+		boolean success;
+		if (excludeRect == null) {
+			success = OS.TrackPopupMenu (handle, flags, nX, nY, 0, hwndParent, null);
+		} else {
+			TPMPARAMS lptpm = new TPMPARAMS();
+			lptpm.cbSize = TPMPARAMS.sizeof;
+			lptpm.left = excludeRect.left;
+			lptpm.top = excludeRect.top;
+			lptpm.right = excludeRect.right;
+			lptpm.bottom = excludeRect.bottom;
+			success = OS.TrackPopupMenuEx (handle, flags, nX, nY, hwndParent, lptpm);
+		}
 		if (!success && GetMenuItemCount (handle) == 0) {
 			OS.SendMessage (hwndParent, OS.WM_MENUSELECT, 0xFFFF0000, 0);
 		}
Index: Eclipse SWT/wpf/org/eclipse/swt/widgets/ToolItem.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT/wpf/org/eclipse/swt/widgets/ToolItem.java,v
retrieving revision 1.8
diff -u -r1.8 ToolItem.java
--- Eclipse SWT/wpf/org/eclipse/swt/widgets/ToolItem.java	31 May 2007 20:34:10 -0000	1.8
+++ Eclipse SWT/wpf/org/eclipse/swt/widgets/ToolItem.java	15 Jun 2007 08:40:30 -0000
@@ -11,6 +11,7 @@
 package org.eclipse.swt.widgets;
 
  
+import org.eclipse.swt.internal.ToolItemHelper;
 import org.eclipse.swt.internal.wpf.*;
 import org.eclipse.swt.*;
 import org.eclipse.swt.graphics.*;
@@ -38,6 +39,7 @@
 	Control control;
 	String toolTipText;
 	Image disabledImage, hotImage;
+	Menu dropDownMenu;
 	boolean ignoreSelection;
 
 /**
@@ -331,6 +333,24 @@
 }
 
 /**
+ * Returns the receiver's drop-down menu if it has one, or null 
+ * if it does not.
+ * <p>
+ * The drop-down menu is activated when the arrow of an {@link SWT#DROP_DOWN}-styled receiver is pressed.
+ * </p>
+ * 
+ * @return the receiver's drop-down menu
+ * @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 Menu getDropDownMenu () {
+	checkWidget();
+	return dropDownMenu;
+}
+
+/**
  * Returns <code>true</code> if the receiver is enabled, and
  * <code>false</code> otherwise. A disabled control is typically
  * not selectable from the user interface and draws with an
@@ -466,7 +486,14 @@
 		OS.GCHandle_Free (zero);
 		OS.GCHandle_Free (mousePos);
 	}
-	postEvent (SWT.Selection, event);
+	if (event.detail == SWT.ARROW) {
+		sendEvent (SWT.Selection, event);
+		if (event.doit) {
+			ToolItemHelper.showDropDownMenu(this);
+		}
+	} else {
+		postEvent (SWT.Selection, event);
+	}
 }
 
 void HandleUnchecked (int sender, int e) {
@@ -676,6 +703,30 @@
 }
 
 /**
+ * Sets the receiver's drop-down menu to the argument, which may be 
+ * null indicating that no drop-down menu should be displayed.
+ * <p>
+ * If this property is null a drop-down menu can still be displayed manually by adding a
+ * {@link SelectionListener} to the receiver and handling{@link SWT#ARROW} events.
+ * <p>
+ * The drop-down menu is activated when the arrow of an {@link SWT#DROP_DOWN}-styled receiver is pressed.
+ * Attempts to set a drop-dwn menu for a receiver that does not have the {@link SWT#DROP_DOWN}
+ * style are ignored.
+ * </p>
+ * 
+ * @param menu the drop-down menu to be displayed when the receiver's arrow is pressed
+ * @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 void setDropDownMenu (Menu menu) {
+	checkWidget();
+	if ((style & SWT.DROP_DOWN) == 0) return;
+	dropDownMenu = menu;
+}
+
+/**
  * Sets the receiver's hot image to the argument, which may be
  * null indicating that no hot image should be displayed.
  * <p>
Index: Eclipse SWT/carbon/org/eclipse/swt/widgets/ToolItem.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt/Eclipse SWT/carbon/org/eclipse/swt/widgets/ToolItem.java,v
retrieving revision 1.101
diff -u -r1.101 ToolItem.java
--- Eclipse SWT/carbon/org/eclipse/swt/widgets/ToolItem.java	31 May 2007 22:03:57 -0000	1.101
+++ Eclipse SWT/carbon/org/eclipse/swt/widgets/ToolItem.java	15 Jun 2007 08:40:24 -0000
@@ -11,6 +11,7 @@
 package org.eclipse.swt.widgets;
 
 
+import org.eclipse.swt.internal.ToolItemHelper;
 import org.eclipse.swt.internal.carbon.OS;
 import org.eclipse.swt.internal.carbon.ControlButtonContentInfo;
 import org.eclipse.swt.internal.carbon.ControlFontStyleRec;
@@ -48,6 +49,7 @@
 	int width = DEFAULT_SEPARATOR_WIDTH;
 	ToolBar parent;
 	Image hotImage, disabledImage;
+	Menu dropDownMenu;
 	String toolTipText;
 	Control control;
 	boolean selection;
@@ -499,6 +501,24 @@
 }
 
 /**
+ * Returns the receiver's drop-down menu if it has one, or null 
+ * if it does not.
+ * <p>
+ * The drop-down menu is activated when the arrow of an {@link SWT#DROP_DOWN}-styled receiver is pressed.
+ * </p>
+ * 
+ * @return the receiver's drop-down menu
+ * @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 Menu getDropDownMenu () {
+	checkWidget();
+	return dropDownMenu;
+}
+
+/**
  * Returns <code>true</code> if the receiver is enabled, and
  * <code>false</code> otherwise. A disabled control is typically
  * not selectable from the user interface and draws with an
@@ -797,7 +817,10 @@
 			event.detail = SWT.ARROW;
 			event.x = (int) pt.x;
 			event.y = (int) pt.y;
-			postEvent (SWT.Selection, event);				
+			sendEvent (SWT.Selection, event);
+			if (event.doit) {
+				ToolItemHelper.showDropDownMenu (this);
+			}
 		}
 	}	
 	return result;
@@ -1032,6 +1055,30 @@
 }
 
 /**
+ * Sets the receiver's drop-down menu to the argument, which may be 
+ * null indicating that no drop-down menu should be displayed.
+ * <p>
+ * If this property is null a drop-down menu can still be displayed manually by adding a
+ * {@link SelectionListener} to the receiver and handling{@link SWT#ARROW} events.
+ * <p>
+ * The drop-down menu is activated when the arrow of an {@link SWT#DROP_DOWN}-styled receiver is pressed.
+ * Attempts to set a drop-dwn menu for a receiver that does not have the {@link SWT#DROP_DOWN}
+ * style are ignored.
+ * </p>
+ * 
+ * @param menu the drop-down menu to be displayed when the receiver's arrow is pressed
+ * @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 void setDropDownMenu (Menu menu) {
+	checkWidget();
+	if ((style & SWT.DROP_DOWN) == 0) return;
+	dropDownMenu = menu;
+}
+
+/**
  * Sets the receiver's hot image to the argument, which may be
  * null indicating that no hot image should be displayed.
  * <p>
Index: Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/TPMPARAMS.java
===================================================================
RCS file: Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/TPMPARAMS.java
diff -N Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/TPMPARAMS.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/TPMPARAMS.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,8 @@
+package org.eclipse.swt.internal.win32;
+
+public class TPMPARAMS {
+	public int cbSize;
+//	public RECT rcExclude;
+	public int left, top, right, bottom;
+	public static int sizeof =  OS.TPMPARAMS_sizeof ();
+}
Index: Eclipse SWT/common/org/eclipse/swt/internal/ToolItemHelper.java
===================================================================
RCS file: Eclipse SWT/common/org/eclipse/swt/internal/ToolItemHelper.java
diff -N Eclipse SWT/common/org/eclipse/swt/internal/ToolItemHelper.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Eclipse SWT/common/org/eclipse/swt/internal/ToolItemHelper.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,21 @@
+package org.eclipse.swt.internal;
+
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.ToolItem;
+
+public final class ToolItemHelper {
+
+	public static void showDropDownMenu (ToolItem item) {
+		Menu dropDownMenu = item.getDropDownMenu ();	
+		if (dropDownMenu != null) {
+			Rectangle rect = item.getBounds ();
+			Point pt = new Point (rect.x, rect.y + rect.height);
+			pt = item.getParent ().toDisplay (pt);
+			dropDownMenu.setLocation (pt);
+			dropDownMenu.setVisible (true);
+		}
+	}
+
+}
Index: src/org/eclipse/swt/snippets/Snippet67.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet67.java,v
retrieving revision 1.3
diff -u -r1.3 Snippet67.java
--- src/org/eclipse/swt/snippets/Snippet67.java	16 Sep 2005 19:24:37 -0000	1.3
+++ src/org/eclipse/swt/snippets/Snippet67.java	15 Jun 2007 07:49:11 -0000
@@ -32,17 +32,7 @@
 		item.setText ("Item " + i);
 	}
 	final ToolItem item = new ToolItem (toolBar, SWT.DROP_DOWN);
-	item.addListener (SWT.Selection, new Listener () {
-		public void handleEvent (Event event) {
-			if (event.detail == SWT.ARROW) {
-				Rectangle rect = item.getBounds ();
-				Point pt = new Point (rect.x, rect.y + rect.height);
-				pt = toolBar.toDisplay (pt);
-				menu.setLocation (pt.x, pt.y);
-				menu.setVisible (true);
-			}
-		}
-	});
+	item.setDropDownMenu(menu);
 	toolBar.pack ();
 	shell.pack ();
 	shell.open ();
Index: JNI Generation/org/eclipse/swt/tools/internal/org.eclipse.swt.internal.win32.OS.properties
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.swt.tools/JNI Generation/org/eclipse/swt/tools/internal/org.eclipse.swt.internal.win32.OS.properties,v
retrieving revision 1.108
diff -u -r1.108 org.eclipse.swt.internal.win32.OS.properties
--- JNI Generation/org/eclipse/swt/tools/internal/org.eclipse.swt.internal.win32.OS.properties	15 May 2007 14:28:52 -0000	1.108
+++ JNI Generation/org/eclipse/swt/tools/internal/org.eclipse.swt.internal.win32.OS.properties	15 Jun 2007 06:56:20 -0000
@@ -4582,6 +4582,14 @@
 OS_TrackPopupMenu_5=cast=(HWND)
 OS_TrackPopupMenu_6=
 
+OS_TrackPopupMenuEx=
+OS_TrackPopupMenuEx_0=
+OS_TrackPopupMenuEx_1=
+OS_TrackPopupMenuEx_2=
+OS_TrackPopupMenuEx_3=
+OS_TrackPopupMenuEx_4=
+OS_TrackPopupMenuEx_5=
+
 OS_TranslateAcceleratorA=
 OS_TranslateAcceleratorA_0=cast=(HWND)
 OS_TranslateAcceleratorA_1=cast=(HACCEL)
@@ -5112,6 +5120,13 @@
 TOOLINFO_lParam=
 TOOLINFO_lpReserved=cast=(void *)
 
+org_eclipse_swt_internal_win32_TPMPARAMS=
+TPMPARAMS_cbSize=
+TPMPARAMS_left=accessor=rcExclude.left
+TPMPARAMS_top=accessor=rcExclude.top
+TPMPARAMS_right=accessor=rcExclude.right
+TPMPARAMS_bottom=accessor=rcExclude.bottom
+
 org_eclipse_swt_internal_win32_TRACKMOUSEEVENT=
 TRACKMOUSEEVENT_cbSize=
 TRACKMOUSEEVENT_dwFlags=

Attachment: Drop-Downs the Right Way.pdf
Description: Adobe PDF document


Back to the top