diff options
author | Xi Yan | 2018-07-04 20:50:22 +0000 |
---|---|---|
committer | Xi Yan | 2018-07-10 14:01:04 +0000 |
commit | 90b11d0439eaf39696ee5c80da07e42a77c9ce34 (patch) | |
tree | 027b8adc86ca8e7dc511c24491196ba183ca64b4 | |
parent | 2ef6954b2724f4b0e6be7d10562b1cdac3ce7206 (diff) | |
download | eclipse.platform.swt-90b11d0439eaf39696ee5c80da07e42a77c9ce34.tar.gz eclipse.platform.swt-90b11d0439eaf39696ee5c80da07e42a77c9ce34.tar.xz eclipse.platform.swt-90b11d0439eaf39696ee5c80da07e42a77c9ce34.zip |
Bug 531882 (Snippet230_tableCol_icon_packing) - [Gtk3] Snippet230,
tablecolumn icons on right size get cut off
1) In GTK3, event.width in PaintItem is the same as the one previously
set in MeasureItem. Snippet230 paints icons at the default event.width
position on the right of text in PaintItem, so the icons were painted
too far right as a result. This was fixed by explicitly setting
event.width to be used in PaintItem to the default event.width using
gtk_cell_renderer_set_fixed_size.
2) Custom drawn icons in the expander column of Tree is not positioned
correctly. Fixed by adding expander arrow indent in the x position.
3) Calling TreeColumn#pack() for the first time do not account for the
indent in the expander column because
gtk_tree_view_get_expander_column() returns 0 if expander column is not
visible. This was fixed by setting column to visible beforehand in
Tree#calculateWidth.
Change-Id: I04a26c94ff716c1a52c84d2dbe8ef96386b17035
Signed-off-by: Xi Yan <xixiyan@redhat.com>
3 files changed, 141 insertions, 5 deletions
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 354719a79d..c34d6ba611 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 @@ -2864,7 +2864,7 @@ void sendMeasureEvent (long /*int*/ cell, long /*int*/ width, long /*int*/ heigh if (width != 0) C.memmove (width, contentWidth, 4); if (height != 0) C.memmove (height, contentHeight, 4); if (GTK.GTK3) { - GTK.gtk_cell_renderer_set_fixed_size (cell, contentWidth [0], contentHeight [0]); + GTK.gtk_cell_renderer_set_fixed_size (cell, -1, contentHeight [0]); } } } 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 4de1357b69..49200c04c9 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 @@ -427,7 +427,19 @@ int calculateWidth (long /*int*/ column, long /*int*/ iter, boolean recurse) { int [] w = new int [1]; long /*int*/ path = 0; - if (GTK.gtk_tree_view_get_expander_column (handle) == column) { + /* + * gtk_tree_view_get_expander_column() returns 0 if the expander column is not visible. + * When pack is called for the first time, the expander arrow indent is not added to + * the width for the expander column. The fix is to always get the expander column as if + * it is visible. + */ + long /*int*/ expander_column = GTK.gtk_tree_view_get_expander_column(handle); + if (expander_column == 0 && !GTK.gtk_tree_view_column_get_visible(column)) { + GTK.gtk_tree_view_column_set_visible(column, true); + expander_column = GTK.gtk_tree_view_get_expander_column(handle); + GTK.gtk_tree_view_column_set_visible(column, false); + } + if (expander_column == column) { /* indent */ GdkRectangle rect = new GdkRectangle (); GTK.gtk_widget_realize (handle); @@ -435,8 +447,10 @@ int calculateWidth (long /*int*/ column, long /*int*/ iter, boolean recurse) { GTK.gtk_tree_view_get_cell_area (handle, path, column, rect); width += rect.x; /* expander */ - GTK.gtk_widget_style_get (handle, OS.expander_size, w, 0); - width += w [0] + TreeItem.EXPANDER_EXTRA_PADDING; + if (!GTK.gtk_tree_view_column_get_visible(column)) { + GTK.gtk_widget_style_get (handle, OS.expander_size, w, 0); + width += w [0] + TreeItem.EXPANDER_EXTRA_PADDING; + } } GTK.gtk_widget_style_get(handle, OS.focus_line_width, w, 0); width += 2 * w [0]; @@ -2923,7 +2937,7 @@ void sendMeasureEvent (long /*int*/ cell, long /*int*/ width, long /*int*/ heigh if (width != 0) C.memmove (width, contentWidth, 4); if (height != 0) C.memmove (height, contentHeight, 4); if (GTK.GTK3) { - GTK.gtk_cell_renderer_set_fixed_size (cell, contentWidth [0], contentHeight [0]); + GTK.gtk_cell_renderer_set_fixed_size (cell, -1, contentHeight [0]); } } } @@ -3169,6 +3183,16 @@ void rendererRender (long /*int*/ cell, long /*int*/ cr, long /*int*/ window, lo } contentX [0] -= imageWidth; contentWidth [0] += imageWidth; + + // Account for the expander arrow offset in x position + if (GTK.gtk_tree_view_get_expander_column (handle) == columnHandle) { + /* indent */ + GdkRectangle rect3 = new GdkRectangle (); + GTK.gtk_widget_realize (handle); + path = GTK.gtk_tree_model_get_path (modelHandle, iter); + GTK.gtk_tree_view_get_cell_area (handle, path, columnHandle, rect3); + contentX[0] += rect3.x; + } GC gc = getGC(cr); if ((drawState & SWT.SELECTED) != 0) { Color background, foreground; diff --git a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug531882_TreeColIconPacking.java b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug531882_TreeColIconPacking.java new file mode 100644 index 0000000000..09a4bd70ff --- /dev/null +++ b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug531882_TreeColIconPacking.java @@ -0,0 +1,112 @@ +/******************************************************************************* + * Copyright (c) 2018 Red Hat 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: + * Red Hat - initial API and implementation + *******************************************************************************/ +package org.eclipse.swt.tests.gtk.snippets; + +/* + * Tree example snippet: draw images on right side of tree item + * + * For more info on custom-drawing TreeItem and TreeItem content see + * http://www.eclipse.org/articles/article.php?file=Article-CustomDrawingTableAndTreeItems/index.html + * + * For a list of all SWT example snippets see + * http://www.eclipse.org/swt/snippets/ + * + * @since 3.2 + */ +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.swt.widgets.TreeColumn; +import org.eclipse.swt.widgets.TreeItem; + +public class Bug531882_TreeColIconPacking { + +public static void main(String [] args) { + Display display = new Display(); + final Image image = display.getSystemImage(SWT.ICON_INFORMATION); + Shell shell = new Shell(display); + + shell.setText("Images on the right side of the TreeItem"); + shell.setLayout(new FillLayout ()); + + Tree tree = new Tree(shell, SWT.MULTI | SWT.FULL_SELECTION); + tree.setHeaderVisible(true); + tree.setLinesVisible(true); + + int columnCount = 3; + for (int i=0; i<columnCount; i++) { + TreeColumn column = new TreeColumn(tree, SWT.NONE); + column.setText("Column " + i); + } + + int itemCount = 4; + for(int i = 0; i < itemCount; i++) { + TreeItem item = new TreeItem(tree, SWT.NONE); + item.setText(new String[] {"item "+i+" a", "item "+i+" b", "item "+i+" c"}); + for (int j = 0; j < itemCount; j++) { + TreeItem subItem = new TreeItem(item, SWT.NONE); + subItem.setText(new String[] {"sub-item " + j + " a", "sub-item " + j + " b", "sub-item " + j + " c"}); + for (int k = 0; k < itemCount; k++) { + TreeItem kItem = new TreeItem(subItem, SWT.NONE); + kItem.setText(new String[] {"sub-sub-item "+k+" a", "sub-sub-item "+k+" b", "sub-sub-item "+k+" c"}); + } + } + } + + /* + * NOTE: MeasureItem, PaintItem and EraseItem are called repeatedly. + * Therefore, it is critical for performance that these methods be + * as efficient as possible. + */ + Listener paintListener = event -> { + switch(event.type) { + case SWT.MeasureItem: { + Rectangle rect1 = image.getBounds(); + event.width += rect1.width; + event.height = Math.max(event.height, rect1.height + 2); + break; + } + case SWT.PaintItem: { + int x = event.x + event.width; + Rectangle rect2 = image.getBounds(); + int offset = Math.max(0, (event.height - rect2.height) / 2); + event.gc.drawImage(image, x, event.y + offset); + break; + } + } + }; + tree.addListener(SWT.MeasureItem, paintListener); + tree.addListener(SWT.PaintItem, paintListener); + + tree.setVisible(true); + + for(int i = 0; i < columnCount; i++) { + tree.getColumn(i).pack(); + } + +// for(int i = 0; i < columnCount; i++) { +// tree.getColumn(i).pack(); +// } + + shell.setSize(500, 200); + shell.open(); + while(!shell.isDisposed ()) { + if(!display.readAndDispatch()) display.sleep(); + } + if(image != null) image.dispose(); + display.dispose(); +} +} |