diff options
author | Alexandr Miloslavskiy | 2021-12-17 22:39:34 +0000 |
---|---|---|
committer | Alexander Kurtakov | 2022-03-22 10:48:14 +0000 |
commit | b324b57ca1e55a287e2900604c974402a6ed337b (patch) | |
tree | 338563166a7abd08bda9f4664e5ad15949981f16 | |
parent | aaf8d11bb143b05c0163c70e3fc511ca45880ffa (diff) | |
download | eclipse.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>
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(); + } +} |