diff options
author | Billy Biggs <bbiggs> | 2005-02-04 18:59:28 +0000 |
---|---|---|
committer | Billy Biggs <bbiggs> | 2005-02-04 18:59:28 +0000 |
commit | 5782ed835cc34300c35de16696ca0fbe1e498ed9 (patch) | |
tree | 773457d0f3cd1935c355b785c6063663a0cd32ca | |
parent | 28f2c95555bb2ed2b6c2a58fbef9c726a4ca8116 (diff) | |
download | eclipse.platform.swt-5782ed835cc34300c35de16696ca0fbe1e498ed9.tar.gz eclipse.platform.swt-5782ed835cc34300c35de16696ca0fbe1e498ed9.tar.xz eclipse.platform.swt-5782ed835cc34300c35de16696ca0fbe1e498ed9.zip |
31563 - Support zero-sized widgets and optimize widget creation.
10 files changed, 148 insertions, 25 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c index aa5353f823..d4cf8dfff4 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os.c @@ -149,6 +149,46 @@ JNIEXPORT jint JNICALL OS_NATIVE(GTK_1WIDGET_1HEIGHT) } #endif +#ifndef NO_GTK_1WIDGET_1SET_1HEIGHT +JNIEXPORT void JNICALL OS_NATIVE(GTK_1WIDGET_1SET_1HEIGHT) + (JNIEnv *env, jclass that, jint arg0, jint arg1) +{ + OS_NATIVE_ENTER(env, that, GTK_1WIDGET_1SET_1HEIGHT_FUNC); + GTK_WIDGET_SET_HEIGHT(arg0, arg1); + OS_NATIVE_EXIT(env, that, GTK_1WIDGET_1SET_1HEIGHT_FUNC); +} +#endif + +#ifndef NO_GTK_1WIDGET_1SET_1WIDTH +JNIEXPORT void JNICALL OS_NATIVE(GTK_1WIDGET_1SET_1WIDTH) + (JNIEnv *env, jclass that, jint arg0, jint arg1) +{ + OS_NATIVE_ENTER(env, that, GTK_1WIDGET_1SET_1WIDTH_FUNC); + GTK_WIDGET_SET_WIDTH(arg0, arg1); + OS_NATIVE_EXIT(env, that, GTK_1WIDGET_1SET_1WIDTH_FUNC); +} +#endif + +#ifndef NO_GTK_1WIDGET_1SET_1X +JNIEXPORT void JNICALL OS_NATIVE(GTK_1WIDGET_1SET_1X) + (JNIEnv *env, jclass that, jint arg0, jint arg1) +{ + OS_NATIVE_ENTER(env, that, GTK_1WIDGET_1SET_1X_FUNC); + GTK_WIDGET_SET_X(arg0, arg1); + OS_NATIVE_EXIT(env, that, GTK_1WIDGET_1SET_1X_FUNC); +} +#endif + +#ifndef NO_GTK_1WIDGET_1SET_1Y +JNIEXPORT void JNICALL OS_NATIVE(GTK_1WIDGET_1SET_1Y) + (JNIEnv *env, jclass that, jint arg0, jint arg1) +{ + OS_NATIVE_ENTER(env, that, GTK_1WIDGET_1SET_1Y_FUNC); + GTK_WIDGET_SET_Y(arg0, arg1); + OS_NATIVE_EXIT(env, that, GTK_1WIDGET_1SET_1Y_FUNC); +} +#endif + #ifndef NO_GTK_1WIDGET_1WIDTH JNIEXPORT jint JNICALL OS_NATIVE(GTK_1WIDGET_1WIDTH) (JNIEnv *env, jclass that, jint arg0) diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h index c47e7ca846..480b7ee28c 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_custom.h @@ -53,12 +53,16 @@ #define GTK_SCROLLED_WINDOW_SCROLLBAR_SPACING(arg0) (GTK_SCROLLED_WINDOW_GET_CLASS (arg0)->scrollbar_spacing >= 0 ? GTK_SCROLLED_WINDOW_GET_CLASS (arg0)->scrollbar_spacing : 3) #define GTK_SCROLLED_WINDOW_VSCROLLBAR(arg0) (arg0)->vscrollbar #define GTK_WIDGET_HEIGHT(arg0) (arg0)->allocation.height +#define GTK_WIDGET_SET_HEIGHT(arg0, arg1) ((GtkWidget *)arg0)->allocation.height = arg1 #define GTK_WIDGET_WIDTH(arg0) (arg0)->allocation.width +#define GTK_WIDGET_SET_WIDTH(arg0, arg1) ((GtkWidget *)arg0)->allocation.width = arg1 #define GTK_WIDGET_WINDOW(arg0) (arg0)->window #define GTK_WIDGET_X(arg0) (arg0)->allocation.x +#define GTK_WIDGET_SET_X(arg0, arg1) ((GtkWidget *)arg0)->allocation.x = arg1 #define GTK_ENTRY_IM_CONTEXT(arg0) (arg0)->im_context #define GTK_TEXTVIEW_IM_CONTEXT(arg0) (arg0)->im_context #define GTK_WIDGET_Y(arg0) ((GtkWidget *)arg0)->allocation.y +#define GTK_WIDGET_SET_Y(arg0, arg1) ((GtkWidget *)arg0)->allocation.y = arg1 #define g_list_data(arg0) (arg0)->data #define g_slist_data(arg0) (arg0)->data #define g_list_set_next(arg0, arg1) (arg0)->next = arg1 diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c index 0b3332cbf2..a8f21e097b 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.c @@ -18,8 +18,8 @@ #ifdef NATIVE_STATS -int OS_nativeFunctionCount = 958; -int OS_nativeFunctionCallCount[958]; +int OS_nativeFunctionCount = 962; +int OS_nativeFunctionCallCount[962]; char * OS_nativeFunctionNames[] = { "Call", "GDK_1WINDOWING_1X11", @@ -33,6 +33,10 @@ char * OS_nativeFunctionNames[] = { "GTK_1SCROLLED_1WINDOW_1VSCROLLBAR", "GTK_1TEXTVIEW_1IM_1CONTEXT", "GTK_1WIDGET_1HEIGHT", + "GTK_1WIDGET_1SET_1HEIGHT", + "GTK_1WIDGET_1SET_1WIDTH", + "GTK_1WIDGET_1SET_1X", + "GTK_1WIDGET_1SET_1Y", "GTK_1WIDGET_1WIDTH", "GTK_1WIDGET_1WINDOW", "GTK_1WIDGET_1X", diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h index 94d12eb6a7..e722c712fb 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/library/os_stats.h @@ -37,6 +37,10 @@ typedef enum { GTK_1SCROLLED_1WINDOW_1VSCROLLBAR_FUNC, GTK_1TEXTVIEW_1IM_1CONTEXT_FUNC, GTK_1WIDGET_1HEIGHT_FUNC, + GTK_1WIDGET_1SET_1HEIGHT_FUNC, + GTK_1WIDGET_1SET_1WIDTH_FUNC, + GTK_1WIDGET_1SET_1X_FUNC, + GTK_1WIDGET_1SET_1Y_FUNC, GTK_1WIDGET_1WIDTH_FUNC, GTK_1WIDGET_1WINDOW_FUNC, GTK_1WIDGET_1X_FUNC, diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java index 0c81a06da0..4f1b47f40d 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java +++ b/bundles/org.eclipse.swt/Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java @@ -492,6 +492,10 @@ public static final native void GTK_ACCEL_LABEL_SET_ACCEL_STRING(int /*long*/ ac public static final native int /*long*/ GTK_ACCEL_LABEL_GET_ACCEL_STRING(int /*long*/ acce_label); public static final native int /*long*/ GTK_ENTRY_IM_CONTEXT(int /*long*/ widget); public static final native int /*long*/ GTK_TEXTVIEW_IM_CONTEXT(int /*long*/ widget); +public static final native void GTK_WIDGET_SET_HEIGHT(int /*long*/ widget, int height); +public static final native void GTK_WIDGET_SET_WIDTH(int /*long*/ widget, int width); +public static final native void GTK_WIDGET_SET_X(int /*long*/ widget, int x); +public static final native void GTK_WIDGET_SET_Y(int /*long*/ widget, int y); /** X11 Native methods and constants */ public static final int Above = 0; diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java index 2369463a33..5f2e87d7fb 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Control.java @@ -412,6 +412,9 @@ public Rectangle getBounds () { int /*long*/ topHandle = topHandle (); int x = OS.GTK_WIDGET_X (topHandle); int y = OS.GTK_WIDGET_Y (topHandle); + if ((state & ZERO_SIZED) != 0) { + return new Rectangle (x, y, 0, 0); + } int width = OS.GTK_WIDGET_WIDTH (topHandle); int height = OS.GTK_WIDGET_HEIGHT (topHandle); return new Rectangle (x, y, width, height); @@ -521,19 +524,22 @@ int setBounds (int x, int y, int width, int height, boolean move, boolean resize } } if (resize) { - width = Math.max (1, width); - height = Math.max (1, height); - int oldWidth = OS.GTK_WIDGET_WIDTH (topHandle); - int oldHeight = OS.GTK_WIDGET_HEIGHT (topHandle); + int oldWidth = 0, oldHeight = 0; + if ((state & ZERO_SIZED) == 0) { + oldWidth = OS.GTK_WIDGET_WIDTH (topHandle); + oldHeight = OS.GTK_WIDGET_HEIGHT (topHandle); + } sameExtent = width == oldWidth && height == oldHeight; - if (!sameExtent) { + if (!sameExtent && !(width == 0 && height == 0)) { + int newWidth = Math.max (1, width); + int newHeight = Math.max (1, height); if (redrawWindow != 0) { - OS.gdk_window_resize (redrawWindow, width, height); + OS.gdk_window_resize (redrawWindow, newWidth, newHeight); } if (enableWindow != 0) { - OS.gdk_window_resize (enableWindow, width, height); + OS.gdk_window_resize (enableWindow, newWidth, newHeight); } - resizeHandle (width, height); + resizeHandle (newWidth, newHeight); } } if (!sameOrigin || !sameExtent) { @@ -546,6 +552,28 @@ int setBounds (int x, int y, int width, int height, boolean move, boolean resize if ((flags & OS.GTK_VISIBLE) == 0) { OS.GTK_WIDGET_UNSET_FLAGS (topHandle, OS.GTK_VISIBLE); } + /* + * Bug in GTK. Widgets cannot be sized smaller than 1x1. + * The fix is to hide zero-sized widgets and show them again + * when they are resized larger. + */ + if (!sameExtent) { + if (width == 0 && height == 0) { + state |= ZERO_SIZED; + if (enableWindow != 0) { + OS.gdk_window_hide (enableWindow); + } + OS.gtk_widget_hide (topHandle); + } else { + state &= ~ZERO_SIZED; + if ((state & HIDDEN) == 0) { + if (enableWindow != 0) { + OS.gdk_window_show_unraised (enableWindow); + } + OS.gtk_widget_show (topHandle); + } + } + } int result = 0; if (move && !sameOrigin) { sendEvent (SWT.Move); @@ -634,6 +662,9 @@ public void setLocation(int x, int y) { */ public Point getSize () { checkWidget(); + if ((state & ZERO_SIZED) != 0) { + return new Point (0, 0); + } int /*long*/ topHandle = topHandle (); int width = OS.GTK_WIDGET_WIDTH (topHandle); int height = OS.GTK_WIDGET_HEIGHT (topHandle); @@ -1713,7 +1744,7 @@ public String getToolTipText () { */ public boolean getVisible () { checkWidget(); - return OS.GTK_WIDGET_VISIBLE (topHandle ()); + return (state & HIDDEN) == 0; } int /*long*/ gtk_button_press_event (int /*long*/ widget, int /*long*/ event) { @@ -2115,7 +2146,7 @@ boolean isShowing () { Control control = this; while (control != null) { Point size = control.getSize (); - if (size.x == 1 || size.y == 1) { + if (size.x == 0 || size.y == 0) { return false; } control = control.parent; @@ -2245,6 +2276,7 @@ void register () { */ public void redraw () { checkWidget(); + if (!OS.GTK_WIDGET_VISIBLE (topHandle ())) return; int /*long*/ paintHandle = paintHandle (); int width = OS.GTK_WIDGET_WIDTH (paintHandle); int height = OS.GTK_WIDGET_HEIGHT (paintHandle); @@ -2282,6 +2314,7 @@ public void redraw () { */ public void redraw (int x, int y, int width, int height, boolean all) { checkWidget(); + if (!OS.GTK_WIDGET_VISIBLE (topHandle ())) return; redrawWidget (x, y, width, height, all); } @@ -2668,12 +2701,26 @@ void setForegroundColor (GdkColor color) { } void setInitialSize () { - resizeHandle (1, 1); - /* - * Force the container to allocate the size of its children. - */ - int /*long*/ parentHandle = parent.parentingHandle (); - OS.gtk_container_resize_children (parentHandle); + // Comment this line to disable zero-sized widgets + state |= ZERO_SIZED; + if ((state & ZERO_SIZED) != 0) { + /* + * Feature in GTK. On creation, each widget's allocation is + * initialized to a position of (-1, -1) until the widget is + * first sized. The fix is to set the value to (0, 0) as + * expected by SWT. + */ + int /*long*/ topHandle = topHandle (); + OS.GTK_WIDGET_SET_X (topHandle, 0); + OS.GTK_WIDGET_SET_Y (topHandle, 0); + } else { + resizeHandle (1, 1); + /* + * Force the container to allocate the size of its children. + */ + int /*long*/ parentHandle = parent.parentingHandle (); + OS.gtk_container_resize_children (parentHandle); + } } /** @@ -2857,8 +2904,8 @@ public void setToolTipText (String string) { */ public void setVisible (boolean visible) { checkWidget(); + if (((state & HIDDEN) == 0) == visible) return; int /*long*/ topHandle = topHandle(); - if ((OS.GTK_WIDGET_VISIBLE (topHandle) == visible)) return; if (visible) { /* * It is possible (but unlikely), that application @@ -2867,8 +2914,11 @@ public void setVisible (boolean visible) { */ sendEvent (SWT.Show); if (isDisposed ()) return; - if (enableWindow != 0) OS.gdk_window_show_unraised (enableWindow); - OS.gtk_widget_show (topHandle); + state &= ~HIDDEN; + if ((state & ZERO_SIZED) == 0) { + if (enableWindow != 0) OS.gdk_window_show_unraised (enableWindow); + OS.gtk_widget_show (topHandle); + } } else { /* * Bug in GTK. Invoking gtk_widget_hide() on a widget that has @@ -2891,6 +2941,7 @@ public void setVisible (boolean visible) { if (isDisposed ()) return; OS.GTK_WIDGET_SET_FLAGS (topHandle, OS.GTK_VISIBLE); } + state |= HIDDEN; OS.gtk_widget_hide (topHandle); if (enableWindow != 0) OS.gdk_window_hide (enableWindow); sendEvent (SWT.Hide); @@ -2984,8 +3035,10 @@ void showWidget () { int /*long*/ topHandle = topHandle (); int /*long*/ parentHandle = parent.parentingHandle (); OS.gtk_container_add (parentHandle, topHandle); - if (handle != 0) OS.gtk_widget_show (handle); - if (fixedHandle != 0) OS.gtk_widget_show (fixedHandle); + if (handle != 0 && handle != topHandle) OS.gtk_widget_show (handle); + if ((state & ZERO_SIZED) == 0) { + if (fixedHandle != 0) OS.gtk_widget_show (fixedHandle); + } } void sort (int [] items) { @@ -3234,6 +3287,7 @@ public void update () { void update (boolean all) { // checkWidget(); + if (!OS.GTK_WIDGET_VISIBLE (topHandle ())) return; if ((OS.GTK_WIDGET_FLAGS (handle) & OS.GTK_REALIZED) == 0) return; int /*long*/ window = paintWindow (); display.flushExposes (window, all); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Group.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Group.java index 1dfa17875a..0fd3ba5f46 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Group.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Group.java @@ -173,6 +173,9 @@ void fixGroup () { public Rectangle getClientArea () { checkWidget(); + if ((state & ZERO_SIZED) != 0) { + return new Rectangle (0, 0, 0, 0); + } int width = OS.GTK_WIDGET_WIDTH (clientHandle); int height = OS.GTK_WIDGET_HEIGHT (clientHandle); return new Rectangle (0, 0, width, height); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Scrollable.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Scrollable.java index c4173ecc73..06e52d4d7f 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Scrollable.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Scrollable.java @@ -184,8 +184,11 @@ public Rectangle getClientArea () { checkWidget (); //FIXME - List, Table, Tree, ... int /*long*/ clientHandle = clientHandle (); - int width = OS.GTK_WIDGET_WIDTH (clientHandle); - int height = OS.GTK_WIDGET_HEIGHT (clientHandle); + int width = 0, height = 0; + if ((state & ZERO_SIZED) == 0) { + width = OS.GTK_WIDGET_WIDTH (clientHandle); + height = OS.GTK_WIDGET_HEIGHT (clientHandle); + } if ((state & CANVAS) != 0) { return new Rectangle (0, 0, width, height); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java index 52a8bb384c..6d434bc955 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Shell.java @@ -662,6 +662,11 @@ public Point getSize () { return new Point (width + trimWidth (), height + trimHeight ()); } +public boolean getVisible () { + checkWidget(); + return OS.GTK_WIDGET_VISIBLE (shellHandle); +} + /** * Returns the region that defines the shape of the shell, * or null if the shell has the default shape. diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java index f21f56eea5..96f999133e 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java @@ -71,6 +71,8 @@ public abstract class Widget { static final int RESIZED = 1<<8; static final int LAYOUT_NEEDED = 1<<9; static final int LAYOUT_CHANGED = 1<<10; + static final int ZERO_SIZED = 1<<11; + static final int HIDDEN = 1<<12; /* Default widths for widgets */ static final int DEFAULT_WIDTH = 64; |