Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandr Miloslavskiy2021-12-17 22:39:34 +0000
committerAlexander Kurtakov2022-03-22 10:48:14 +0000
commitb324b57ca1e55a287e2900604c974402a6ed337b (patch)
tree338563166a7abd08bda9f4664e5ad15949981f16
parentaaf8d11bb143b05c0163c70e3fc511ca45880ffa (diff)
downloadeclipse.platform.swt-b324b57ca1e55a287e2900604c974402a6ed337b.tar.gz
eclipse.platform.swt-b324b57ca1e55a287e2900604c974402a6ed337b.tar.xz
eclipse.platform.swt-b324b57ca1e55a287e2900604c974402a6ed337b.zip
Bug 577878 - [GTK] Table/Tree with SWT.PaintItem don't show rows when dragging them
Rendering drag images for SWT.PaintItem case was "temporarily" disabled for a very long time, since commit 5a8028d0 by Steve Northover at 2008-04-29 07:56:43 disable drag images in table and tree for custom draw It didn't work well, because instead of using `background_area` callback argument, it requested the value via `gtk_tree_view_get_background_area()`, which returns screen coordinates in Tree/Table. However, in case of rendering a drag image, an isolated row is rendered, and coordinates are different. Change-Id: I816fcd32ad6a7fee92f93ac2ff600f7cac444989 Signed-off-by: Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com> Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.swt/+/188983 Tested-by: Platform Bot <platform-bot@eclipse.org> Reviewed-by: Alexander Kurtakov <akurtako@redhat.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TableDragSourceEffect.java2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeDragSourceEffect.java2
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GdkRectangle.java5
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java24
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java27
-rw-r--r--tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug577878_GTK_TreeTable_NoDragImageWithPaintItem.java151
6 files changed, 177 insertions, 34 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TableDragSourceEffect.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TableDragSourceEffect.java
index af900f9731..ac4df82f19 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TableDragSourceEffect.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TableDragSourceEffect.java
@@ -86,8 +86,6 @@ public class TableDragSourceEffect extends DragSourceEffect {
dragSourceImage = null;
Table table = (Table) control;
- //TEMPORARY CODE
- if (table.isListening(SWT.EraseItem) || table.isListening (SWT.PaintItem)) return null;
/*
* Bug in GTK. gtk_tree_selection_get_selected_rows() segmentation faults
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeDragSourceEffect.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeDragSourceEffect.java
index d48a177f1c..9163528e4b 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeDragSourceEffect.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/gtk/org/eclipse/swt/dnd/TreeDragSourceEffect.java
@@ -85,8 +85,6 @@ public class TreeDragSourceEffect extends DragSourceEffect {
dragSourceImage = null;
Tree tree = (Tree) control;
- //TEMPORARY CODE
- if (tree.isListening(SWT.EraseItem) || tree.isListening (SWT.PaintItem)) return null;
/*
* Bug in GTK. gtk_tree_selection_get_selected_rows() segmentation faults
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GdkRectangle.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GdkRectangle.java
index 4e547d07e8..7623e32142 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GdkRectangle.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/GdkRectangle.java
@@ -14,6 +14,7 @@
*******************************************************************************/
package org.eclipse.swt.internal.gtk;
+import org.eclipse.swt.graphics.Rectangle;
public class GdkRectangle {
/** @field cast=(gint) */
@@ -36,4 +37,8 @@ public class GdkRectangle {
public String toString() {
return "GdkRectangle {" + x + ", " + y + ", " + width + ", " + height + "}"; //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
}
+
+ public Rectangle toRectangle() {
+ return new Rectangle(x, y, width, height);
+ }
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
index 1e0ec9eca1..35a1834607 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java
@@ -2961,6 +2961,10 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
}
}
}
+
+ GdkRectangle backround_area_rect = new GdkRectangle ();
+ OS.memmove (backround_area_rect, background_area, GdkRectangle.sizeof);
+
if (item != null) {
if (GTK.GTK_IS_CELL_RENDERER_TOGGLE (cell) || (columnIndex != 0 || (style & SWT.CHECK) == 0)) {
drawFlags = (int)flags;
@@ -2980,10 +2984,7 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
if ((flags & GTK.GTK_CELL_RENDERER_FOCUSED) != 0) drawState |= SWT.FOCUSED;
}
- GdkRectangle rect = new GdkRectangle ();
- long path = GTK.gtk_tree_model_get_path (modelHandle, iter);
- GTK.gtk_tree_view_get_background_area (handle, path, columnHandle, rect);
- GTK.gtk_tree_path_free (path);
+ Rectangle rect = backround_area_rect.toRectangle ();
if ((drawState & SWT.SELECTED) == 0) {
if ((state & PARENT_BACKGROUND) != 0 || backgroundImage != null) {
Control control = findBackgroundControl ();
@@ -3029,11 +3030,11 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
if (cr != 0) {
GdkRectangle r = new GdkRectangle();
GDK.gdk_cairo_get_clip_rectangle(cr, r);
- Rectangle rect2 = DPIUtil.autoScaleDown(new Rectangle(rect.x, r.y, r.width, r.height));
+ Rectangle rect2 = DPIUtil.autoScaleDown(rect);
// Caveat: rect2 is necessary because GC#setClipping(Rectangle) got broken by bug 446075
gc.setClipping(rect2.x, rect2.y, rect2.width, rect2.height);
} else {
- Rectangle rect2 = DPIUtil.autoScaleDown(new Rectangle(rect.x, rect.y, rect.width, rect.height));
+ Rectangle rect2 = DPIUtil.autoScaleDown(rect);
// Caveat: rect2 is necessary because GC#setClipping(Rectangle) got broken by bug 446075
gc.setClipping(rect2.x, rect2.y, rect2.width, rect2.height);
@@ -3074,9 +3075,7 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
if ((drawState & SWT.BACKGROUND) != 0 && (drawState & SWT.SELECTED) == 0) {
GC gc = getGC(cr);
gc.setBackground (item.getBackground (columnIndex));
- GdkRectangle rect = new GdkRectangle ();
- OS.memmove (rect, background_area, GdkRectangle.sizeof);
- gc.fillRectangle(DPIUtil.autoScaleDown(new Rectangle(rect.x, rect.y, rect.width, rect.height)));
+ gc.fillRectangle (DPIUtil.autoScaleDown (backround_area_rect.toRectangle ()));
gc.dispose ();
}
if ((drawState & SWT.FOREGROUND) != 0 || GTK.GTK_IS_CELL_RENDERER_TOGGLE (cell)) {
@@ -3102,10 +3101,7 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
if (GTK.GTK_IS_CELL_RENDERER_TEXT (cell)) {
if (hooks (SWT.PaintItem)) {
if (wasSelected) drawState |= SWT.SELECTED;
- GdkRectangle rect = new GdkRectangle ();
- long path = GTK.gtk_tree_model_get_path (modelHandle, iter);
- GTK.gtk_tree_view_get_background_area (handle, path, columnHandle, rect);
- GTK.gtk_tree_path_free (path);
+ Rectangle rect = backround_area_rect.toRectangle ();
ignoreSize = true;
int [] contentX = new int [1], contentWidth = new int [1];
gtk_cell_renderer_get_preferred_size (cell, handle, contentWidth, null);
@@ -3149,7 +3145,7 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
gc.setFont (item.getFont (columnIndex));
if ((style & SWT.MIRRORED) != 0) rect.x = getClientWidth () - rect.width - rect.x;
- Rectangle rect2 = DPIUtil.autoScaleDown(new Rectangle(rect.x, rect.y, rect.width, rect.height));
+ Rectangle rect2 = DPIUtil.autoScaleDown(rect);
// Caveat: rect2 is necessary because GC#setClipping(Rectangle) got broken by bug 446075
gc.setClipping(rect2.x, rect2.y, rect2.width, rect2.height);
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
index 081a47493c..a5fda907a1 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java
@@ -3168,6 +3168,10 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
}
}
}
+
+ GdkRectangle backround_area_rect = new GdkRectangle ();
+ OS.memmove (backround_area_rect, background_area, GdkRectangle.sizeof);
+
if (item != null) {
if (GTK.GTK_IS_CELL_RENDERER_TOGGLE (cell) || ( columnIndex != 0 || (style & SWT.CHECK) == 0)) {
drawFlags = (int)flags;
@@ -3187,10 +3191,7 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
if ((flags & GTK.GTK_CELL_RENDERER_FOCUSED) != 0) drawState |= SWT.FOCUSED;
}
- GdkRectangle rect = new GdkRectangle ();
- long path = GTK.gtk_tree_model_get_path (modelHandle, iter);
- GTK.gtk_tree_view_get_background_area (handle, path, columnHandle, rect);
- GTK.gtk_tree_path_free (path);
+ Rectangle rect = backround_area_rect.toRectangle ();
// Use the x and width information from the Cairo context. See bug 535124.
if (cr != 0) {
GdkRectangle r2 = new GdkRectangle ();
@@ -3243,10 +3244,10 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
if (cr != 0) {
// Use the original rectangle, not the Cairo clipping for the y, width, and height values.
// See bug 535124.
- Rectangle rect2 = DPIUtil.autoScaleDown(new Rectangle(rect.x, rect.y, rect.width, rect.height));
+ Rectangle rect2 = DPIUtil.autoScaleDown(rect);
gc.setClipping(rect2.x, rect2.y, rect2.width, rect2.height);
} else {
- Rectangle rect2 = DPIUtil.autoScaleDown(new Rectangle(rect.x, rect.y, rect.width, rect.height));
+ Rectangle rect2 = DPIUtil.autoScaleDown(rect);
// Caveat: rect2 is necessary because GC#setClipping(Rectangle) got broken by bug 446075
gc.setClipping(rect2.x, rect2.y, rect2.width, rect2.height);
}
@@ -3275,12 +3276,9 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
}
}
if ((drawState & SWT.BACKGROUND) != 0 && (drawState & SWT.SELECTED) == 0) {
-
GC gc = getGC(cr);
gc.setBackground (item.getBackground (columnIndex));
- GdkRectangle rect = new GdkRectangle ();
- OS.memmove (rect, background_area, GdkRectangle.sizeof);
- gc.fillRectangle(DPIUtil.autoScaleDown(new Rectangle(rect.x, rect.y, rect.width, rect.height)));
+ gc.fillRectangle (DPIUtil.autoScaleDown (backround_area_rect.toRectangle ()));
gc.dispose ();
}
if ((drawState & SWT.FOREGROUND) != 0 || GTK.GTK_IS_CELL_RENDERER_TOGGLE (cell)) {
@@ -3306,10 +3304,7 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
if (GTK.GTK_IS_CELL_RENDERER_TEXT (cell)) {
if (hooks (SWT.PaintItem)) {
if (wasSelected) drawState |= SWT.SELECTED;
- GdkRectangle rect = new GdkRectangle ();
- long path = GTK.gtk_tree_model_get_path (modelHandle, iter);
- GTK.gtk_tree_view_get_background_area (handle, path, columnHandle, rect);
- GTK.gtk_tree_path_free (path);
+ Rectangle rect = backround_area_rect.toRectangle ();
ignoreSize = true;
int [] contentX = new int [1], contentWidth = new int [1];
gtk_cell_renderer_get_preferred_size (cell, handle, contentWidth, null);
@@ -3339,7 +3334,7 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
/* indent */
GdkRectangle rect3 = new GdkRectangle ();
GTK.gtk_widget_realize (handle);
- path = GTK.gtk_tree_model_get_path (modelHandle, iter);
+ long path = GTK.gtk_tree_model_get_path (modelHandle, iter);
GTK.gtk_tree_view_get_cell_area (handle, path, columnHandle, rect3);
GTK.gtk_tree_path_free (path);
contentX[0] += rect3.x;
@@ -3362,7 +3357,7 @@ void rendererRender (long cell, long cr, long snapshot, long widget, long backgr
rect.x = getClientWidth () - rect.width - rect.x;
}
- Rectangle rect2 = DPIUtil.autoScaleDown(new Rectangle(rect.x, rect.y, rect.width, rect.height));
+ Rectangle rect2 = DPIUtil.autoScaleDown(rect);
// Caveat: rect2 is necessary because GC#setClipping(Rectangle) got broken by bug 446075
gc.setClipping(rect2.x, rect2.y, rect2.width, rect2.height);
diff --git a/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug577878_GTK_TreeTable_NoDragImageWithPaintItem.java b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug577878_GTK_TreeTable_NoDragImageWithPaintItem.java
new file mode 100644
index 0000000000..2d65286870
--- /dev/null
+++ b/tests/org.eclipse.swt.tests/ManualTests/org/eclipse/swt/tests/manual/Bug577878_GTK_TreeTable_NoDragImageWithPaintItem.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2021, 2022 Syntevo and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Syntevo - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.swt.tests.manual;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.dnd.*;
+import org.eclipse.swt.layout.*;
+import org.eclipse.swt.widgets.*;
+
+public final class Bug577878_GTK_TreeTable_NoDragImageWithPaintItem {
+ static final int NUM_ROWS = 100;
+ static final int NUM_COLS = 3;
+
+ static String makeItemText(int iRow, int iCol) {
+ return "Item#" + iRow + ":" + iCol;
+ }
+
+ static void createTable(Composite parent, boolean isCustomPaint) {
+ Table control = new Table (parent, SWT.BORDER | SWT.V_SCROLL);
+ control.setLayoutData (new GridData (SWT.FILL, SWT.FILL, true, true));
+
+ control.setHeaderVisible (true);
+ for (int iColumn = 0; iColumn < 3; iColumn++) {
+ TableColumn column = new TableColumn (control, 0);
+ column.setText ("Col#" + iColumn);
+ column.setWidth (120);
+ }
+
+ control.setItemCount (NUM_ROWS);
+
+ if (isCustomPaint) {
+ control.addListener (SWT.MeasureItem, e -> {
+ e.width = 120;
+ e.height = 20;
+ });
+
+ control.addListener (SWT.PaintItem, e -> {
+ TableItem item = (TableItem) e.item;
+ int iRow = item.getParent ().indexOf (item);
+ String text = makeItemText(iRow, e.index);
+ e.gc.drawString (text, e.x, e.y, true);
+ });
+ } else {
+ for (int iRow = 0; iRow < NUM_ROWS; iRow++) {
+ for (int iCol = 0; iCol < NUM_COLS; iCol++) {
+ control.getItem (iRow).setText (iCol, makeItemText(iRow, iCol));
+ }
+ }
+ }
+
+ DragSource dragSource = new DragSource (control, DND.DROP_MOVE | DND.DROP_COPY);
+ dragSource.setTransfer (TextTransfer.getInstance ());
+ dragSource.addDragListener (new DragSourceAdapter ());
+ }
+
+ static void createTree(Composite parent, boolean isCustomPaint) {
+ Tree control = new Tree (parent, SWT.BORDER | SWT.V_SCROLL);
+ control.setLayoutData (new GridData (SWT.FILL, SWT.FILL, true, true));
+
+ control.setHeaderVisible (true);
+ for (int iColumn = 0; iColumn < 3; iColumn++) {
+ TreeColumn column = new TreeColumn (control, 0);
+ column.setText ("Col#" + iColumn);
+ column.setWidth (120);
+ }
+
+ control.setItemCount (NUM_ROWS);
+
+ if (isCustomPaint) {
+ control.addListener (SWT.MeasureItem, e -> {
+ e.width = 120;
+ e.height = 20;
+ });
+
+ control.addListener (SWT.PaintItem, e -> {
+ TreeItem item = (TreeItem) e.item;
+ TreeItem parentItem = item.getParentItem ();
+ int iRow = (parentItem != null) ? parentItem.indexOf (item) : item.getParent ().indexOf (item);
+ String text = makeItemText(iRow, e.index);
+ e.gc.drawString (text, e.x, e.y, true);
+ });
+ } else {
+ for (int iRow = 0; iRow < NUM_ROWS; iRow++) {
+ for (int iCol = 0; iCol < NUM_COLS; iCol++) {
+ control.getItem (iRow).setText (iCol, makeItemText(iRow, iCol));
+ }
+ }
+ }
+
+ TreeItem child = new TreeItem (control.getItem(1), 0);
+ if (!isCustomPaint) {
+ for (int iCol = 0; iCol < NUM_COLS; iCol++) {
+ child.setText (iCol, makeItemText(0, iCol));
+ }
+ }
+
+ DragSource dragSource = new DragSource (control, DND.DROP_MOVE | DND.DROP_COPY);
+ dragSource.setTransfer (TextTransfer.getInstance ());
+ dragSource.addDragListener (new DragSourceAdapter ());
+ }
+
+ public static void main(String[] args) {
+ final Display display = new Display();
+ final Shell shell = new Shell(display);
+ shell.setLayout (new GridLayout (1, true));
+
+ Label hint = new Label(shell, 0);
+ hint.setText (
+ "1) Run on GTK\n" +
+ "2) Drag rows from regular Table/Tree - there will be a drag image\n" +
+ "3) Bug 577878: Table/Tree with SWT.PaintItem do not have drag image\n"
+ );
+
+ Composite composite = new Composite (shell, 0);
+ composite.setLayoutData (new GridData (SWT.FILL, SWT.FILL, true, true));
+ composite.setLayout (new GridLayout (2, true));
+
+ new Label(composite, 0).setText ("Table");
+ new Label(composite, 0).setText ("Table+PaintItem");
+ createTable(composite, false);
+ createTable(composite, true);
+
+ new Label(composite, 0).setText ("Tree");
+ new Label(composite, 0).setText ("Tree+PaintItem");
+ createTree(composite, false);
+ createTree(composite, true);
+
+ shell.setSize (800, 800);
+ shell.open();
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+
+ display.dispose();
+ }
+}

Back to the top