This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
Patch: fix GtkTextFieldPeer's preferred and minimum sizecalculations
- From: Thomas Fitzsimmons <fitzsim at redhat dot com>
- To: libgcj patches <java-patches at gcc dot gnu dot org>
- Date: Tue, 13 Jan 2004 23:28:26 -0500
- Subject: Patch: fix GtkTextFieldPeer's preferred and minimum sizecalculations
Hello,
This patch fixes GtkTextFieldPeer's preferred size and minimum size
calculations. Previously, the preferred and minimum size methods always
returned the actual size of the backing GtkEntry widget, causing
TextField components to be laid out incorrectly.
OK to commit?
Tom
2004-01-13 Thomas Fitzsimmons <fitzsim@redhat.com>
* gnu/java/awt/peer/gtk/GtkTextFieldPeer.java,
jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c
(native create): Add width parameter.
(create): Calculate text entry width based on current font's
metrics and number of columns. Set TextField's font if not
already set. Call native create.
(gtkEntryGetBorderWidth): New native method.
(gtkEntryGetSize): Remove method.
(getMinimumSize): Call minimumSize.
(getPreferredSize): Call preferredSize.
(minimumSize): Calculate minimum size based on backing
GtkEntry's borders, font metrics and number of columns.
(preferredSize): Likewise for preferred size.
(get_border_width): New static function.
Index: gnu/java/awt/peer/gtk/GtkTextFieldPeer.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/java/awt/peer/gtk/GtkTextFieldPeer.java,v
retrieving revision 1.8
diff -u -r1.8 GtkTextFieldPeer.java
--- gnu/java/awt/peer/gtk/GtkTextFieldPeer.java 8 Oct 2003 23:38:44 -0000 1.8
+++ gnu/java/awt/peer/gtk/GtkTextFieldPeer.java 14 Jan 2004 04:12:27 -0000
@@ -41,6 +41,7 @@
import java.awt.AWTEvent;
import java.awt.Dimension;
import java.awt.Font;
+import java.awt.FontMetrics;
import java.awt.TextField;
import java.awt.event.KeyEvent;
import java.awt.peer.TextFieldPeer;
@@ -48,14 +49,38 @@
public class GtkTextFieldPeer extends GtkTextComponentPeer
implements TextFieldPeer
{
+ native void create (int width);
-// native void create (ComponentPeer parent, String text);
+ void create ()
+ {
+ Font f = awtComponent.getFont ();
+
+ // By default, Sun sets a TextField's font when its peer is
+ // created. If f != null then the peer's font is set by
+ // GtkComponent.create.
+ if (f == null)
+ {
+ f = new Font ("Fixed", Font.PLAIN, 12);
+ awtComponent.setFont (f);
+ }
+
+ FontMetrics fm;
+ if (GtkToolkit.useGraphics2D ())
+ fm = new GdkClasspathFontPeerMetrics (f);
+ else
+ fm = new GdkFontMetrics (f);
- native void create ();
+ TextField tf = ((TextField) awtComponent);
+ int cols = tf.getColumns ();
+
+ int text_width = cols * fm.getMaxAdvance ();
+
+ create (text_width);
+ }
- native void gtkEntryGetSize (int dims[]);
+ native int gtkEntryGetBorderWidth ();
- native void gtkSetFont(String name, int style, int size);
+ native void gtkSetFont (String name, int style, int size);
public GtkTextFieldPeer (TextField tf)
{
@@ -67,34 +92,61 @@
public Dimension getMinimumSize (int cols)
{
- int dims[] = new int[2];
-
- gtkEntryGetSize (dims);
-
- return (new Dimension (dims[0], dims[1]));
+ return minimumSize (cols);
}
public Dimension getPreferredSize (int cols)
{
- int dims[] = new int[2];
-
- gtkEntryGetSize (dims);
-
- return (new Dimension (dims[0], dims[1]));
+ return preferredSize (cols);
}
-
- public native void setEchoChar (char c);
- /* Deprecated */
+ public native void setEchoChar (char c);
+ // Deprecated
public Dimension minimumSize (int cols)
{
- return getMinimumSize (cols);
+ int dim[] = new int[2];
+
+ gtkWidgetGetPreferredDimensions (dim);
+
+ Font f = awtComponent.getFont ();
+ if (f == null)
+ return new Dimension (2 * gtkEntryGetBorderWidth (), dim[1]);
+
+ FontMetrics fm;
+ if (GtkToolkit.useGraphics2D ())
+ fm = new GdkClasspathFontPeerMetrics (f);
+ else
+ fm = new GdkFontMetrics (f);
+
+ int text_width = cols * fm.getMaxAdvance ();
+
+ int width = text_width + 2 * gtkEntryGetBorderWidth ();
+
+ return new Dimension (width, dim[1]);
}
public Dimension preferredSize (int cols)
{
- return getPreferredSize (cols);
+ int dim[] = new int[2];
+
+ gtkWidgetGetPreferredDimensions (dim);
+
+ Font f = awtComponent.getFont ();
+ if (f == null)
+ return new Dimension (2 * gtkEntryGetBorderWidth (), dim[1]);
+
+ FontMetrics fm;
+ if (GtkToolkit.useGraphics2D ())
+ fm = new GdkClasspathFontPeerMetrics (f);
+ else
+ fm = new GdkFontMetrics (f);
+
+ int text_width = cols * fm.getMaxAdvance ();
+
+ int width = text_width + 2 * gtkEntryGetBorderWidth ();
+
+ return new Dimension (width, dim[1]);
}
public void setEchoCharacter (char c)
@@ -104,18 +156,18 @@
public void setFont (Font f)
{
- gtkSetFont(f.getName(), f.getStyle(), f.getSize());
+ gtkSetFont (f.getName (), f.getStyle (), f.getSize ());
}
public void handleEvent (AWTEvent e)
{
if (e.getID () == KeyEvent.KEY_PRESSED)
{
- KeyEvent ke = (KeyEvent)e;
+ KeyEvent ke = (KeyEvent) e;
- if (!ke.isConsumed()
- && ke.getKeyCode() == KeyEvent.VK_ENTER)
- postActionEvent (getText(), ke.getModifiers ());
+ if (!ke.isConsumed ()
+ && ke.getKeyCode () == KeyEvent.VK_ENTER)
+ postActionEvent (getText (), ke.getModifiers ());
}
super.handleEvent (e);
Index: jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c
===================================================================
RCS file: /cvs/gcc/gcc/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c,v
retrieving revision 1.9
diff -u -r1.9 gnu_java_awt_peer_gtk_GtkTextFieldPeer.c
--- jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c 13 Dec 2003 01:15:47 -0000 1.9
+++ jni/gtk-peer/gnu_java_awt_peer_gtk_GtkTextFieldPeer.c 14 Jan 2004 04:12:27 -0000
@@ -39,48 +39,74 @@
#include "gtkpeer.h"
#include "gnu_java_awt_peer_gtk_GtkTextFieldPeer.h"
+static jint
+get_border_width (GtkWidget *entry);
+
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_create
- (JNIEnv *env, jobject obj)
+ (JNIEnv *env, jobject obj, jint text_width)
{
- GtkWidget *widget;
+ GtkWidget *entry;
/* Create global reference and save it for future use */
NSA_SET_GLOBAL_REF (env, obj);
gdk_threads_enter ();
-
- widget = gtk_entry_new ();
+
+ entry = gtk_entry_new ();
+ gtk_widget_set_size_request (entry,
+ text_width + 2 * get_border_width (entry), -1);
gdk_threads_leave ();
- NSA_SET_PTR (env, obj, widget);
+ NSA_SET_PTR (env, obj, entry);
}
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkEntryGetSize
- (JNIEnv *env, jobject obj, jintArray jdims)
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkEntryGetBorderWidth
+ (JNIEnv *env, jobject obj)
{
void *ptr;
- jint *dims;
- GtkRequisition myreq;
- GtkWidget *entry;
-
+ int border_width = 0;
+
ptr = NSA_GET_PTR (env, obj);
- dims = (*env)->GetIntArrayElements (env, jdims, 0);
-
+
gdk_threads_enter ();
-
- entry = GTK_WIDGET (ptr);
- gtk_widget_size_request(entry, &myreq);
- dims[0]=myreq.width;
- dims[1]=myreq.height;
-
+
+ border_width = get_border_width (GTK_WIDGET (ptr));
+
gdk_threads_leave ();
-
- (*env)->ReleaseIntArrayElements (env, jdims, dims, 0);
+
+ return border_width;
+}
+
+/* GTK hard-codes this value. It is the space between a GtkEntry's
+ frame and its text. */
+#define INNER_BORDER 2
+
+static jint
+get_border_width (GtkWidget *entry)
+{
+ gint focus_width;
+ gboolean interior_focus;
+ int x_border_width = INNER_BORDER;
+
+ gtk_widget_style_get (entry,
+ "interior-focus", &interior_focus,
+ "focus-line-width", &focus_width,
+ NULL);
+
+ if (GTK_ENTRY (entry)->has_frame)
+ x_border_width += entry->style->xthickness;
+
+ if (!interior_focus)
+ x_border_width += focus_width;
+
+ return x_border_width;
}
+#undef INNER_BORDER
+
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_setEchoChar
(JNIEnv *env, jobject obj, jchar c)
@@ -93,10 +119,12 @@
gdk_threads_enter ();
entry = GTK_ENTRY (ptr);
-
- if (c!=0)
+
+ if (c != 0)
{
-/* gtk_entry_set_echo_char (entry, c); */
+ /* FIXME: use gtk_entry_set_invisible_char (GtkEntry *entry,
+ gunichar ch) here. That means we must convert from jchar
+ (utf16) to gunichar (ucs4). */
gtk_entry_set_visibility (entry, FALSE);
}
else