This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]