From 6037221c71ac41ed1971a58f1cb00e71da657665 Mon Sep 17 00:00:00 2001 From: Thomas Fitzsimmons Date: Mon, 5 Jan 2004 21:35:33 +0000 Subject: [PATCH] 2004-01-05 Thomas Fitzsimmons * gnu/java/awt/peer/gtk/GtkScrollPanePeer.java, jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c (create(int, int)): New method. (create): Call new create method. (gtkScrolledWindowNew, gtkScrolledWindowSetSize): Remove methods. (childResized): Remove native implementation. Implement in Java. (getHScrollbarHeight, getVScrollbarWidth): Call gtk_widget_size_request to get scrollbar dimensions. * java/awt/ScrollPane.java (getViewportSize): Reimplement. Only call getVScrollbarWidth and getHScrollbarHeight when vertical and horizontal scrollbars respectively are needed. (doLayout): Enlarge child if it is smaller than the viewport. From-SVN: r75446 --- libjava/ChangeLog | 17 ++++ .../java/awt/peer/gtk/GtkScrollPanePeer.java | 31 +++++-- libjava/java/awt/ScrollPane.java | 85 +++++++++++++++++-- .../gnu_java_awt_peer_gtk_GtkScrollPanePeer.c | 45 +++++----- 4 files changed, 142 insertions(+), 36 deletions(-) diff --git a/libjava/ChangeLog b/libjava/ChangeLog index c3d654529e5..a86cbb77779 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,20 @@ +2004-01-05 Thomas Fitzsimmons + + * gnu/java/awt/peer/gtk/GtkScrollPanePeer.java, + jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c + (create(int, int)): New method. + (create): Call new create method. + (gtkScrolledWindowNew, gtkScrolledWindowSetSize): Remove + methods. + (childResized): Remove native implementation. Implement in + Java. + (getHScrollbarHeight, getVScrollbarWidth): Call + gtk_widget_size_request to get scrollbar dimensions. + * java/awt/ScrollPane.java (getViewportSize): Reimplement. Only + call getVScrollbarWidth and getHScrollbarHeight when vertical + and horizontal scrollbars respectively are needed. + (doLayout): Enlarge child if it is smaller than the viewport. + 2004-01-05 Fernando Nasser * java/awt/Dialog.java (constructor): Accept null title as per spec. diff --git a/libjava/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java b/libjava/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java index cd2c112c283..e4f5e8f312c 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java @@ -46,15 +46,17 @@ import java.awt.peer.ScrollPanePeer; public class GtkScrollPanePeer extends GtkContainerPeer implements ScrollPanePeer { - native void create (); + native void create (int width, int height); + + void create () + { + create (awtComponent.getWidth (), awtComponent.getHeight ()); + } - native void gtkScrolledWindowNew(ComponentPeer parent, - int policy, int w, int h, int[] dims); native void gtkScrolledWindowSetScrollPosition(int x, int y); native void gtkScrolledWindowSetHScrollIncrement (int u); native void gtkScrolledWindowSetVScrollIncrement (int u); - native void gtkScrolledWindowSetSize(int w, int h); - + public GtkScrollPanePeer (ScrollPane sp) { super (sp); @@ -63,7 +65,24 @@ public class GtkScrollPanePeer extends GtkContainerPeer } native void setPolicy (int policy); - native public void childResized (int width, int height); + public void childResized (int width, int height) + { + int dim[] = new int[2]; + + gtkWidgetGetDimensions (dim); + + // If the child is in this range, GTK adds both scrollbars, but + // the AWT doesn't. So set the peer's scroll policy to + // GTK_POLICY_NEVER. + if ((width > dim[0] - getVScrollbarWidth () + && width <= dim[0]) + && (height > dim[1] - getHScrollbarHeight () + && height <= dim[1])) + setPolicy (ScrollPane.SCROLLBARS_NEVER); + else + setPolicy (((ScrollPane) awtComponent).getScrollbarDisplayPolicy ()); + } + native public int getHScrollbarHeight (); native public int getVScrollbarWidth (); native public void setScrollPosition (int x, int y); diff --git a/libjava/java/awt/ScrollPane.java b/libjava/java/awt/ScrollPane.java index ceb45680514..937568a6204 100644 --- a/libjava/java/awt/ScrollPane.java +++ b/libjava/java/awt/ScrollPane.java @@ -218,12 +218,71 @@ public Dimension getViewportSize () { Dimension viewsize = getSize (); Insets insets = getInsets (); - viewsize.width = (viewsize.width - - (insets.left + insets.right) - - getVScrollbarWidth ()); - viewsize.height = (viewsize.height - - (insets.top + insets.bottom) - - getHScrollbarHeight ()); + + viewsize.width -= (insets.left + insets.right); + viewsize.height -= (insets.top + insets.bottom); + + Component[] list = getComponents(); + if ((list == null) || (list.length <= 0)) + return viewsize; + + Dimension dim = list[0].getPreferredSize(); + + if (dim.width <= 0 && dim.height <= 0) + return viewsize; + + int vScrollbarWidth = getVScrollbarWidth (); + int hScrollbarHeight = getHScrollbarHeight (); + + if (scrollbarDisplayPolicy == SCROLLBARS_ALWAYS) + { + viewsize.width -= vScrollbarWidth; + viewsize.height -= hScrollbarHeight; + return viewsize; + } + + if (scrollbarDisplayPolicy == SCROLLBARS_NEVER) + return viewsize; + + // The scroll policy is SCROLLBARS_AS_NEEDED, so we need to see if + // either scrollbar is needed. + + // Assume we don't need either scrollbar. + boolean mayNeedVertical = false; + boolean mayNeedHorizontal = false; + + boolean needVertical = false; + boolean needHorizontal = false; + + // Check if we need vertical scrollbars. If we do, then we need to + // subtract the width of the vertical scrollbar from the viewport's + // width. + if (dim.height > viewsize.height) + needVertical = true; + else if (dim.height > (viewsize.height - hScrollbarHeight)) + // This is tricky. In this case the child is tall enough that its + // bottom edge would be covered by a horizontal scrollbar, if one + // were present. This means that if there's a horizontal + // scrollbar then we need a vertical scrollbar. + mayNeedVertical = true; + + if (dim.width > viewsize.width) + needHorizontal = true; + else if (dim.width > (viewsize.width - vScrollbarWidth)) + mayNeedHorizontal = true; + + if (needVertical && mayNeedHorizontal) + needHorizontal = true; + + if (needHorizontal && mayNeedVertical) + needVertical = true; + + if (needHorizontal) + viewsize.height -= hScrollbarHeight; + + if (needVertical) + viewsize.width -= vScrollbarWidth; + return viewsize; } @@ -391,7 +450,19 @@ doLayout() if ((list != null) && (list.length > 0)) { Dimension dim = list[0].getPreferredSize(); - list[0].resize(dim); + Dimension vp = getViewportSize (); + + if (dim.width < vp.width) + dim.width = vp.width; + + if (dim.height < vp.height) + dim.height = vp.height; + + ScrollPanePeer peer = (ScrollPanePeer) getPeer (); + if (peer != null) + peer.childResized (dim.width, dim.height); + + list[0].resize (dim); Point p = getScrollPosition(); if (p.x > dim.width) diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c index 516797e7eb4..79e5082bbb1 100644 --- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c +++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c @@ -41,20 +41,22 @@ exception statement from your version. */ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_create - (JNIEnv *env, jobject obj) + (JNIEnv *env, jobject obj, int width, int height) { - gpointer window; + GtkWidget *sw; /* Create global reference and save it for future use */ NSA_SET_GLOBAL_REF (env, obj); gdk_threads_enter (); - window = gtk_scrolled_window_new (NULL, NULL); + sw = gtk_scrolled_window_new (NULL, NULL); + + gtk_widget_set_size_request (sw, width, height); gdk_threads_leave (); - NSA_SET_PTR (env, obj, window); + NSA_SET_PTR (env, obj, sw); } JNIEXPORT void JNICALL @@ -116,34 +118,25 @@ Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_gtkScrolledWindowSetVScrollIncremen gdk_threads_leave (); } -JNIEXPORT void JNICALL -Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_childResized - (JNIEnv *env, jobject obj, jint width, jint height) -{ - void *ptr; - - ptr = NSA_GET_PTR (env, obj); - - return; - - gdk_threads_enter (); - gtk_widget_set_usize (GTK_BIN (ptr)->child, width, height); - gdk_threads_leave (); -} - JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_getHScrollbarHeight (JNIEnv *env, jobject obj) { void *ptr; GtkScrolledWindow *sw; - jint height; + GtkRequisition requisition; + jint height = 0; + jint spacing = 0; ptr = NSA_GET_PTR (env, obj); gdk_threads_enter (); sw = GTK_SCROLLED_WINDOW (ptr); - height = (sw->hscrollbar_visible) ? sw->hscrollbar->allocation.height : 0; + + gtk_widget_size_request (sw->hscrollbar, &requisition); + gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL); + height = requisition.height + spacing; + gdk_threads_leave (); return height; @@ -155,13 +148,19 @@ Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_getVScrollbarWidth { void *ptr; GtkScrolledWindow *sw; - jint width; + GtkRequisition requisition; + jint width = 0; + jint spacing = 0; ptr = NSA_GET_PTR (env, obj); gdk_threads_enter (); sw = GTK_SCROLLED_WINDOW (ptr); - width = (sw->vscrollbar_visible) ? sw->vscrollbar->allocation.width : 0; + + gtk_widget_size_request (sw->vscrollbar, &requisition); + gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL); + width = requisition.width + spacing; + gdk_threads_leave (); return width;