Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Pun2016-06-13 18:50:39 +0000
committerEric Williams2016-06-23 17:59:19 +0000
commit7e5f98bb2b5f6f1dadb9ec6a9723c4817caab045 (patch)
tree1d7d2fbd842298ea5fc3268c96e0e04613fef23e
parent3df7914e708c9f0930766ef4855d5f1c32429635 (diff)
downloadeclipse.platform.swt-7e5f98bb2b5f6f1dadb9ec6a9723c4817caab045.tar.gz
eclipse.platform.swt-7e5f98bb2b5f6f1dadb9ec6a9723c4817caab045.tar.xz
eclipse.platform.swt-7e5f98bb2b5f6f1dadb9ec6a9723c4817caab045.zip
Bug 495909 - [GTK3.20+]
test_setTopItemLorg_eclipse_swt_widgets_TreeItem() fails Referring to bug Bug 461354, I used a topIndex variable to keep track of the top item. Check to see if there has been any scrolling changes done by the user, and if not, return the topIndex variable. We can keep track of scrolling changes by using a cachedAdjustment variable with a currentAdjustment variable grabbed with GTK functions. This optimization has also been adapted on the Table widget. Tested on GTK 2, 3.14, .16, .18, and .20. Change-Id: Icf5ebbf3b075ab06f54914c1c753041c9205f820 Signed-off-by: Ian Pun <ipun@redhat.com>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java51
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java58
-rw-r--r--tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Table.java18
3 files changed, 107 insertions, 20 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 e1f84ec38a..8c88ab328e 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
@@ -83,6 +83,8 @@ public class Table extends Composite {
GdkRGBA background;
boolean ownerDraw, ignoreSize, ignoreAccessibility, pixbufSizeSet;
int maxWidth = 0;
+ int topIndex;
+ double cachedAdjustment, currentAdjustment;
static final int CHECKED_COLUMN = 0;
static final int GRAYED_COLUMN = 1;
@@ -1890,15 +1892,31 @@ long /*int*/ getTextRenderer (long /*int*/ column) {
*/
public int getTopIndex () {
checkWidget();
- long /*int*/ [] path = new long /*int*/ [1];
- OS.gtk_widget_realize (handle);
- if (!OS.gtk_tree_view_get_path_at_pos (handle, 1, 1, path, null, null, null)) return 0;
- if (path [0] == 0) return 0;
- long /*int*/ indices = OS.gtk_tree_path_get_indices (path[0]);
- int[] index = new int [1];
- if (indices != 0) OS.memmove (index, indices, 4);
- OS.gtk_tree_path_free (path [0]);
- return index [0];
+ /*
+ * Feature in GTK: fetch the topIndex using the topItem global variable
+ * if setTopIndex() has been called and the widget has not been scrolled
+ * using the UI. Otherwise, fetch topIndex using GtkTreeView API.
+ */
+ long /*int*/ vAdjustment;
+ if (OS.GTK3){
+ vAdjustment = OS.gtk_scrollable_get_vadjustment(handle);
+ } else {
+ vAdjustment = OS.gtk_tree_view_get_vadjustment(handle);
+ }
+ currentAdjustment = OS.gtk_adjustment_get_value(vAdjustment);
+ if (cachedAdjustment == currentAdjustment){
+ return topIndex;
+ } else {
+ long /*int*/ [] path = new long /*int*/ [1];
+ OS.gtk_widget_realize (handle);
+ if (!OS.gtk_tree_view_get_path_at_pos (handle, 1, 1, path, null, null, null)) return 0;
+ if (path [0] == 0) return 0;
+ long /*int*/ indices = OS.gtk_tree_path_get_indices (path[0]);
+ int[] index = new int [1];
+ if (indices != 0) OS.memmove (index, indices, 4);
+ OS.gtk_tree_path_free (path [0]);
+ return index [0];
+ }
}
@Override
@@ -3681,6 +3699,21 @@ public void setSelection (TableItem [] items) {
public void setTopIndex (int index) {
checkWidget();
if (!(0 <= index && index < itemCount)) return;
+ /*
+ * Feature in GTK: cache the GtkAdjustment value for future use in
+ * getTopIndex(). Set topIndex to index.
+ *
+ * Use gtk_tree_view_get_view_get_vadjustment for GTK2, GtkScrollable
+ * doesn't exist on GTK2.
+ */
+ long /*int*/ vAdjustment;
+ if (OS.GTK3){
+ vAdjustment = OS.gtk_scrollable_get_vadjustment(handle);
+ } else {
+ vAdjustment = OS.gtk_tree_view_get_vadjustment(handle);
+ }
+ cachedAdjustment = OS.gtk_adjustment_get_value(vAdjustment);
+ topIndex = index;
long /*int*/ path = OS.gtk_tree_model_get_path (modelHandle, _getItem (index).handle);
OS.gtk_tree_view_scroll_to_cell (handle, path, 0, true, 0f, 0f);
OS.gtk_tree_path_free (path);
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 c8d6c232cf..fcedf3321d 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
@@ -92,6 +92,8 @@ public class Tree extends Composite {
GdkRGBA background;
boolean ownerDraw, ignoreSize, ignoreAccessibility, pixbufSizeSet;
int pixbufHeight, pixbufWidth;
+ TreeItem topItem;
+ double cachedAdjustment, currentAdjustment;
static final int ID_COLUMN = 0;
static final int CHECKED_COLUMN = 1;
@@ -1880,18 +1882,36 @@ long /*int*/ getTextRenderer (long /*int*/ column) {
*/
public TreeItem getTopItem () {
checkWidget ();
- long /*int*/ [] path = new long /*int*/ [1];
- OS.gtk_widget_realize (handle);
- if (!OS.gtk_tree_view_get_path_at_pos (handle, 1, 1, path, null, null, null)) return null;
- if (path [0] == 0) return null;
- TreeItem item = null;
- long /*int*/ iter = OS.g_malloc (OS.GtkTreeIter_sizeof());
- if (OS.gtk_tree_model_get_iter (modelHandle, iter, path [0])) {
- item = _getItem (iter);
+ /*
+ * Feature in GTK: fetch the topItem using the topItem global variable
+ * if setTopItem() has been called and the widget has not been scrolled
+ * using the UI. Otherwise, fetch topItem using GtkTreeView API.
+ */
+ long /*int*/ vAdjustment;
+ if (OS.GTK3) {
+ vAdjustment = OS.gtk_scrollable_get_vadjustment(handle);
+ }
+ else {
+ vAdjustment = OS.gtk_tree_view_get_vadjustment(handle);
+ }
+ cachedAdjustment = OS.gtk_adjustment_get_value(vAdjustment);
+ currentAdjustment = OS._gtk_adjustment_get_value(vAdjustment);
+ if (cachedAdjustment==currentAdjustment){
+ return topItem;
+ } else {
+ long /*int*/ [] path = new long /*int*/ [1];
+ OS.gtk_widget_realize (handle);
+ if (!OS.gtk_tree_view_get_path_at_pos (handle, 1, 1, path, null, null, null)) return null;
+ if (path [0] == 0) return null;
+ TreeItem item = null;
+ long /*int*/ iter = OS.g_malloc (OS.GtkTreeIter_sizeof());
+ if (OS.gtk_tree_model_get_iter (modelHandle, iter, path [0])) {
+ item = _getItem (iter);
+ }
+ OS.g_free (iter);
+ OS.gtk_tree_path_free (path [0]);
+ return item;
}
- OS.g_free (iter);
- OS.gtk_tree_path_free (path [0]);
- return item;
}
@Override
@@ -3529,6 +3549,22 @@ public void setTopItem (TreeItem item) {
if (item == null) error (SWT.ERROR_NULL_ARGUMENT);
if (item.isDisposed ()) error(SWT.ERROR_INVALID_ARGUMENT);
if (item.parent != this) return;
+ /*
+ * Feature in GTK: cache the GtkAdjustment value for future use in
+ * getTopItem(). Set topItem to item.
+ *
+ * Use gtk_tree_view_get_view_get_vadjustment for GTK2, GtkScrollable
+ * doesn't exist on GTK2.
+ */
+ long /*int*/ vAdjustment;
+ if (OS.GTK3) {
+ vAdjustment = OS.gtk_scrollable_get_vadjustment(handle);
+ }
+ else {
+ vAdjustment = OS.gtk_tree_view_get_vadjustment(handle);
+ }
+ cachedAdjustment = OS.gtk_adjustment_get_value(vAdjustment);
+ topItem= item;
long /*int*/ path = OS.gtk_tree_model_get_path (modelHandle, item.handle);
showItem (path, false);
OS.gtk_tree_view_scroll_to_cell (handle, path, 0, true, 0, 0);
diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Table.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Table.java
index 302eab1298..a91e9dcab2 100644
--- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Table.java
+++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Table.java
@@ -1775,4 +1775,22 @@ public void test_Virtual() {
dataCounter[0] > visibleCount / 2 && dataCounter[0] <= visibleCount * 2);
}
+@Test
+public void test_setTopIndex() {
+ for (int i = 0; i < 10; i++) {
+ new TableItem(table, 0);
+ }
+ TableItem top = new TableItem(table, 0);
+ for (int i = 0; i < 10; i++) {
+ new TableItem(table, 0);
+ }
+ table.setSize(50,50);
+ shell.open();
+ table.setTopIndex(5);
+ for (int i = 0; i < 10; i++) {
+ new TableItem(table, 0);
+ }
+ shell.setVisible(false);
+ assertEquals(5, table.getTopIndex());
+}
}

Back to the top