This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch: ScrollPane fixes
- From: Thomas Fitzsimmons <fitzsim at redhat dot com>
- To: java-patches at gcc dot gnu dot org
- Date: Mon, 29 Dec 2003 16:25:25 -0500
- Subject: Patch: ScrollPane fixes
Hello,
If a ScrollPane's child is not as wide as the ScrollPane's viewport,
then the child should be resized so that it is as wide as the viewport.
Likewise in the vertical direction. The resizing wasn't happening with
our ScrollPane implementation, and this patch addresses the problem.
Comments?
Tom
2003-12-29 Thomas Fitzsimmons <fitzsim@redhat.com>
* 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.
Index: gnu/java/awt/peer/gtk/GtkScrollPanePeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java,v
retrieving revision 1.2
diff -u -r1.2 GtkScrollPanePeer.java
--- gnu/java/awt/peer/gtk/GtkScrollPanePeer.java 13 Jul 2003 15:09:20 -0000 1.2
+++ gnu/java/awt/peer/gtk/GtkScrollPanePeer.java 29 Dec 2003 19:20:53 -0000
@@ -46,15 +46,17 @@
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 @@
}
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);
Index: java/awt/ScrollPane.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/awt/ScrollPane.java,v
retrieving revision 1.13
diff -u -r1.13 ScrollPane.java
--- java/awt/ScrollPane.java 5 Jun 2003 19:58:39 -0000 1.13
+++ java/awt/ScrollPane.java 29 Dec 2003 19:20:53 -0000
@@ -218,12 +218,71 @@
{
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 @@
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)
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c,v
retrieving revision 1.3
diff -u -r1.3 gnu_java_awt_peer_gtk_GtkScrollPanePeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c 13 Dec 2003 01:15:47 -0000 1.3
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkScrollPanePeer.c 29 Dec 2003 19:20:53 -0000
@@ -41,20 +41,22 @@
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 @@
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 @@
{
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;