summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Northover <steve>2008-02-05 00:33:12 +0000
committerSteve Northover <steve>2008-02-05 00:33:12 +0000
commit30b3672ceb3d2c5d7c5e65c4765952fcea275186 (patch)
tree8d9266e9b39c2a8691a9b283c66b9ccc36c64317
parent5a4ec706c1fb816c9cff4c4e7493b85db9b7b5b8 (diff)
downloadeclipse.platform.swt-30b3672ceb3d2c5d7c5e65c4765952fcea275186.tar.gz
eclipse.platform.swt-30b3672ceb3d2c5d7c5e65c4765952fcea275186.tar.xz
eclipse.platform.swt-30b3672ceb3d2c5d7c5e65c4765952fcea275186.zip
168807 - SWT.MeasureItem not used for selection hittest
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java137
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java85
2 files changed, 196 insertions, 26 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java
index 7179b139b9..6c04c13772 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Table.java
@@ -74,7 +74,7 @@ public class Table extends Composite {
TableColumn sortColumn;
boolean ignoreCustomDraw, ignoreDrawForeground, ignoreDrawBackground, ignoreDrawFocus, ignoreDrawSelection, ignoreDrawHot;
boolean customDraw, dragStarted, explorerTheme, firstColumnImage, fixScrollWidth, tipRequested, wasSelected, wasResized;
- boolean ignoreActivate, ignoreSelect, ignoreShrink, ignoreResize, ignoreColumnMove, ignoreColumnResize;
+ boolean ignoreActivate, ignoreSelect, ignoreShrink, ignoreResize, ignoreColumnMove, ignoreColumnResize, fullRowSelect;
int /*long*/ headerToolTipHandle;
int itemHeight, lastIndexOf, lastWidth, sortDirection, resizeCount, selectionForeground, hotIndex;
static /*final*/ int /*long*/ HeaderProc;
@@ -2206,8 +2206,33 @@ public TableItem getItem (int index) {
public TableItem getItem (Point point) {
checkWidget ();
if (point == null) error (SWT.ERROR_NULL_ARGUMENT);
+ int count = (int)/*64*/OS.SendMessage (handle, OS.LVM_GETITEMCOUNT, 0, 0);
+ if (count == 0) return null;
LVHITTESTINFO pinfo = new LVHITTESTINFO ();
- pinfo.x = point.x; pinfo.y = point.y;
+ pinfo.x = point.x;
+ pinfo.y = point.y;
+ if ((style & SWT.FULL_SELECTION) == 0) {
+ if (hooks (SWT.MeasureItem)) {
+ OS.SendMessage (handle, OS.LVM_SUBITEMHITTEST, 0, pinfo);
+ if (pinfo.iItem == -1) {
+ RECT rect = new RECT ();
+ rect.left = OS.LVIR_ICON;
+ ignoreCustomDraw = true;
+ int /*long*/ code = OS.SendMessage (handle, OS.LVM_GETITEMRECT, 0, rect);
+ ignoreCustomDraw = false;
+ if (code != 0) {
+ pinfo.x = rect.left;
+ OS.SendMessage (handle, OS.LVM_SUBITEMHITTEST, 0, pinfo);
+ }
+ }
+ if (pinfo.iItem != -1 && pinfo.iSubItem == 0) {
+ if (hitTestSelection (pinfo.iItem, pinfo.x, pinfo.y)) {
+ return _getItem (pinfo.iItem);
+ }
+ }
+ return null;
+ }
+ }
OS.SendMessage (handle, OS.LVM_HITTEST, 0, pinfo);
if (pinfo.iItem != -1) {
/*
@@ -2506,6 +2531,28 @@ boolean hasChildren () {
return false;
}
+boolean hitTestSelection (int index, int x, int y) {
+ int count = (int)/*64*/OS.SendMessage (handle, OS.LVM_GETITEMCOUNT, 0, 0);
+ if (count == 0) return false;
+ if (!hooks (SWT.MeasureItem)) return false;
+ boolean result = false;
+ if (0 <= index && index < count) {
+ TableItem item = _getItem (index);
+ int /*long*/ hDC = OS.GetDC (handle);
+ int /*long*/ oldFont = 0, newFont = OS.SendMessage (handle, OS.WM_GETFONT, 0, 0);
+ if (newFont != 0) oldFont = OS.SelectObject (hDC, newFont);
+ int /*long*/ hFont = item.fontHandle (0);
+ if (hFont != -1) hFont = OS.SelectObject (hDC, hFont);
+ Event event = sendMeasureItemEvent (item, index, 0, hDC);
+ if (event.getBounds ().contains (x, y)) result = true;
+ if (hFont != -1) hFont = OS.SelectObject (hDC, hFont);
+ if (newFont != 0) OS.SelectObject (hDC, oldFont);
+ OS.ReleaseDC (handle, hDC);
+// if (isDisposed () || item.isDisposed ()) return false;
+ }
+ return result;
+}
+
int imageIndex (Image image, int column) {
if (image == null) return OS.I_IMAGENONE;
if (column == 0) {
@@ -3326,6 +3373,15 @@ Event sendMeasureItemEvent (TableItem item, int row, int column, int /*long*/ hD
}
LRESULT sendMouseDownEvent (int type, int button, int msg, int /*long*/ wParam, int /*long*/ lParam) {
+ Display display = this.display;
+ display.captureChanged = false;
+ if (!sendMouseEvent (type, button, handle, msg, wParam, lParam)) {
+ if (!display.captureChanged && !isDisposed ()) {
+ if (OS.GetCapture () != handle) OS.SetCapture (handle);
+ }
+ return LRESULT.ZERO;
+ }
+
/*
* Feature in Windows. Inside WM_LBUTTONDOWN and WM_RBUTTONDOWN,
* the widget starts a modal loop to determine if the user wants
@@ -3342,15 +3398,28 @@ LRESULT sendMouseDownEvent (int type, int button, int msg, int /*long*/ wParam,
pinfo.x = OS.GET_X_LPARAM (lParam);
pinfo.y = OS.GET_Y_LPARAM (lParam);
OS.SendMessage (handle, OS.LVM_HITTEST, 0, pinfo);
- Display display = this.display;
- display.captureChanged = false;
- if (!sendMouseEvent (type, button, handle, msg, wParam, lParam)) {
- if (!display.captureChanged && !isDisposed ()) {
- if (OS.GetCapture () != handle) OS.SetCapture (handle);
+ if ((style & SWT.FULL_SELECTION) == 0) {
+ if (hooks (SWT.MeasureItem)) {
+ OS.SendMessage (handle, OS.LVM_SUBITEMHITTEST, 0, pinfo);
+ if (pinfo.iItem == -1) {
+ int count = (int)/*64*/OS.SendMessage (handle, OS.LVM_GETITEMCOUNT, 0, 0);
+ if (count != 0) {
+ RECT rect = new RECT ();
+ rect.left = OS.LVIR_ICON;
+ ignoreCustomDraw = true;
+ int /*long*/ code = OS.SendMessage (handle, OS.LVM_GETITEMRECT, 0, rect);
+ ignoreCustomDraw = false;
+ if (code != 0) {
+ pinfo.x = rect.left;
+ OS.SendMessage (handle, OS.LVM_SUBITEMHITTEST, 0, pinfo);
+ }
+ }
+ } else {
+ if (pinfo.iSubItem != 0) pinfo.iItem = -1;
+ }
}
- return LRESULT.ZERO;
}
-
+
/*
* Force the table to have focus so that when the user
* reselects the focus item, the LVIS_FOCUSED state bits
@@ -3398,6 +3467,17 @@ LRESULT sendMouseDownEvent (int type, int button, int msg, int /*long*/ wParam,
forceSelect = true;
}
}
+
+ /* Determine whether the user has selected an item based on SWT.MeasureItem */
+ fullRowSelect = false;
+ if (pinfo.iItem != -1) {
+ if ((style & SWT.FULL_SELECTION) == 0) {
+ if (hooks (SWT.MeasureItem)) {
+ fullRowSelect = hitTestSelection (pinfo.iItem, pinfo.x, pinfo.y);
+ }
+ }
+ }
+
/*
* Feature in Windows. Inside WM_LBUTTONDOWN and WM_RBUTTONDOWN,
* the widget starts a modal loop to determine if the user wants
@@ -3410,10 +3490,28 @@ LRESULT sendMouseDownEvent (int type, int button, int msg, int /*long*/ wParam,
if (!dragDetect) {
int flags = OS.LVHT_ONITEMICON | OS.LVHT_ONITEMLABEL;
dragDetect = pinfo.iItem == -1 || (pinfo.flags & flags) == 0;
+ if (fullRowSelect) dragDetect = true;
+ }
+
+ /*
+ * Temporarily set LVS_EX_FULLROWSELECT to allow drag and drop
+ * and the mouse to manipulate items based on the results of
+ * the SWT.MeasureItem event.
+ */
+ if (fullRowSelect) {
+ OS.UpdateWindow (handle);
+ OS.DefWindowProc (handle, OS.WM_SETREDRAW, 0, 0);
+ OS.SendMessage (handle, OS.LVM_SETEXTENDEDLISTVIEWSTYLE, OS.LVS_EX_FULLROWSELECT, OS.LVS_EX_FULLROWSELECT);
}
if (!dragDetect) display.runDragDrop = false;
int /*long*/ code = callWindowProc (handle, msg, wParam, lParam, forceSelect);
if (!dragDetect) display.runDragDrop = true;
+ if (fullRowSelect) {
+ fullRowSelect = false;
+ OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0);
+ OS.SendMessage (handle, OS.LVM_SETEXTENDEDLISTVIEWSTYLE, OS.LVS_EX_FULLROWSELECT, 0);
+ }
+
if (dragStarted || !dragDetect) {
if (!display.captureChanged && !isDisposed ()) {
if (OS.GetCapture () != handle) OS.SetCapture (handle);
@@ -5079,6 +5177,22 @@ int /*long*/ windowProc () {
}
int /*long*/ windowProc (int /*long*/ hwnd, int msg, int /*long*/ wParam, int /*long*/ lParam) {
+
+// //#define WM_STYLECHANGING 0x007C #define WM_STYLECHANGED
+// if (msg == 0x007C) {
+// System.out.println("WM_STYLECHANGING");
+// }
+// if (msg == 0x007D) {
+// System.out.println("WM_STYLECHANGED");
+// }
+
+// if (F) {
+// System.out.println("0x" + Integer.toHexString(msg));
+// if (msg == OS.LVM_GETITEMRECT) {
+// System.out.println("LVM_GETITEMRECT");
+// }
+// }
+
if (handle == 0) return 0;
if (hwnd != handle) {
switch (msg) {
@@ -6107,6 +6221,11 @@ LRESULT wmNotifyChild (NMHDR hdr, int /*long*/ wParam, int /*long*/ lParam) {
break;
}
case OS.LVN_ITEMCHANGED: {
+ if (fullRowSelect) {
+ fullRowSelect = false;
+ OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0);
+ OS.SendMessage (handle, OS.LVM_SETEXTENDEDLISTVIEWSTYLE, OS.LVS_EX_FULLROWSELECT, 0);
+ }
if (!ignoreSelect) {
NMLISTVIEW pnmlv = new NMLISTVIEW ();
OS.MoveMemory (pnmlv, lParam, NMLISTVIEW.sizeof);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java
index 396c16a72a..c94048df2c 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Tree.java
@@ -3085,10 +3085,15 @@ public TreeItem getItem (Point point) {
int flags = OS.TVHT_ONITEM;
if ((style & SWT.FULL_SELECTION) != 0) {
flags |= OS.TVHT_ONITEMRIGHT | OS.TVHT_ONITEMINDENT;
+ } else {
+ if (hooks (SWT.MeasureItem)) {
+ lpht.flags &= ~(OS.TVHT_ONITEMICON | OS.TVHT_ONITEMLABEL);
+ if (hitTestSelection (lpht.hItem, lpht.x, lpht.y)) {
+ lpht.flags |= OS.TVHT_ONITEMICON | OS.TVHT_ONITEMLABEL;
+ }
+ }
}
- if ((lpht.flags & flags) != 0) {
- return _getItem (lpht.hItem);
- }
+ if ((lpht.flags & flags) != 0) return _getItem (lpht.hItem);
}
return null;
}
@@ -3519,6 +3524,30 @@ public TreeItem getTopItem () {
return hItem != 0 ? _getItem (hItem) : null;
}
+boolean hitTestSelection (int /*long*/ hItem, int x, int y) {
+ if (hItem == 0) return false;
+ TreeItem item = _getItem (hItem);
+ if (item == null) return false;
+ if (!hooks (SWT.MeasureItem)) return false;
+ boolean result = false;
+
+ //BUG? - moved columns, only hittest first column
+ //BUG? - check drag detect
+ int [] order = new int [1], index = new int [1];
+
+ int /*long*/ hDC = OS.GetDC (handle);
+ int /*long*/ oldFont = 0, newFont = OS.SendMessage (handle, OS.WM_GETFONT, 0, 0);
+ if (newFont != 0) oldFont = OS.SelectObject (hDC, newFont);
+ int /*long*/ hFont = item.fontHandle (order [index [0]]);
+ if (hFont != -1) hFont = OS.SelectObject (hDC, hFont);
+ Event event = sendMeasureItemEvent (item, order [index [0]], hDC);
+ if (event.getBounds ().contains (x, y)) result = true;
+ if (newFont != 0) OS.SelectObject (hDC, oldFont);
+ OS.ReleaseDC (handle, hDC);
+// if (isDisposed () || item.isDisposed ()) return false;
+ return result;
+}
+
int imageIndex (Image image, int index) {
if (image == null) return OS.I_IMAGENONE;
if (imageList == null) {
@@ -5992,6 +6021,13 @@ LRESULT WM_LBUTTONDBLCLK (int /*long*/ wParam, int /*long*/ lParam) {
int flags = OS.TVHT_ONITEM;
if ((style & SWT.FULL_SELECTION) != 0) {
flags |= OS.TVHT_ONITEMRIGHT | OS.TVHT_ONITEMINDENT;
+ } else {
+ if (hooks (SWT.MeasureItem)) {
+ lpht.flags &= ~(OS.TVHT_ONITEMICON | OS.TVHT_ONITEMLABEL);
+ if (hitTestSelection (lpht.hItem, lpht.x, lpht.y)) {
+ lpht.flags |= OS.TVHT_ONITEMICON | OS.TVHT_ONITEMLABEL;
+ }
+ }
}
if ((lpht.flags & flags) != 0) {
Event event = new Event ();
@@ -6115,7 +6151,7 @@ LRESULT WM_LBUTTONDOWN (int /*long*/ wParam, int /*long*/ lParam) {
/* Process the mouse when an item is not selected */
if ((style & SWT.FULL_SELECTION) == 0) {
- if ((lpht.flags & OS.TVHT_ONITEM) == 0) {
+ if ((lpht.flags & OS.TVHT_ONITEM) == 0 && !hooks (SWT.MeasureItem)) {
Display display = this.display;
display.captureChanged = false;
if (!sendMouseEvent (SWT.MouseDown, 1, handle, OS.WM_LBUTTONDOWN, wParam, lParam)) {
@@ -6210,20 +6246,26 @@ LRESULT WM_LBUTTONDOWN (int /*long*/ wParam, int /*long*/ lParam) {
* drawing on top of any custom drawing. The fix
* is to emulate TVS_FULLROWSELECT.
*/
- if ((style & SWT.FULL_SELECTION) != 0) {
- int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
- if ((bits & OS.TVS_FULLROWSELECT) == 0) {
- if (lpht.hItem != 0) {
- if (hOldItem == 0 || (hNewItem == hOldItem && lpht.hItem != hOldItem)) {
- OS.SendMessage (handle, OS.TVM_SELECTITEM, OS.TVGN_CARET, lpht.hItem);
- hNewItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0);
- }
- if (!dragStarted && (state & DRAG_DETECT) != 0 && hooks (SWT.DragDetect)) {
- dragStarted = dragDetect (handle, lpht.x, lpht.y, false, null, null);
- }
+ boolean fakeSelection = false;
+ if (lpht.hItem != 0) {
+ if ((style & SWT.FULL_SELECTION) != 0) {
+ int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
+ if ((bits & OS.TVS_FULLROWSELECT) == 0) fakeSelection = true;
+ } else {
+ if (hooks (SWT.MeasureItem)) {
+ if (hitTestSelection (lpht.hItem, lpht.x, lpht.y)) fakeSelection = true;
}
}
}
+ if (fakeSelection) {
+ if (hOldItem == 0 || (hNewItem == hOldItem && lpht.hItem != hOldItem)) {
+ OS.SendMessage (handle, OS.TVM_SELECTITEM, OS.TVGN_CARET, lpht.hItem);
+ hNewItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0);
+ }
+ if (!dragStarted && (state & DRAG_DETECT) != 0 && hooks (SWT.DragDetect)) {
+ dragStarted = dragDetect (handle, lpht.x, lpht.y, false, null, null);
+ }
+ }
ignoreDeselect = ignoreSelect = false;
hSelect = 0;
if (dragStarted) {
@@ -6459,8 +6501,16 @@ LRESULT WM_RBUTTONDOWN (int /*long*/ wParam, int /*long*/ lParam) {
lpht.y = OS.GET_Y_LPARAM (lParam);
OS.SendMessage (handle, OS.TVM_HITTEST, 0, lpht);
if (lpht.hItem != 0) {
- int flags = OS.TVHT_ONITEMICON | OS.TVHT_ONITEMLABEL;
- if ((style & SWT.FULL_SELECTION) != 0 || (lpht.flags & flags) != 0) {
+ boolean fakeSelection = (style & SWT.FULL_SELECTION) != 0;
+ if (!fakeSelection) {
+ if (hooks (SWT.MeasureItem)) {
+ fakeSelection = hitTestSelection (lpht.hItem, lpht.x, lpht.y);
+ } else {
+ int flags = OS.TVHT_ONITEMICON | OS.TVHT_ONITEMLABEL;
+ fakeSelection = (lpht.flags & flags) != 0;
+ }
+ }
+ if (fakeSelection) {
if ((wParam & (OS.MK_CONTROL | OS.MK_SHIFT)) == 0) {
TVITEM tvItem = new TVITEM ();
tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE;
@@ -6922,6 +6972,7 @@ LRESULT wmNotifyChild (NMHDR hdr, int /*long*/ wParam, int /*long*/ lParam) {
* avoid the operation by testing to see whether
* the mouse was inside a tree item.
*/
+ if (hooks (SWT.MeasureItem)) return LRESULT.ONE;
if (hooks (SWT.DefaultSelection)) {
POINT pt = new POINT ();
int pos = OS.GetMessagePos ();