/* gtklistpeer.c -- Native implementation of GtkListPeer Copyright (C) 1998, 1999 Free Software Foundation, Inc. This file is part of the peer AWT libraries of GNU Classpath. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later verion. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA. */ #include "gtkpeer.h" #include "gnu_java_awt_peer_gtk_GtkListPeer.h" static void connect_selectable_hook (JNIEnv *env, jobject peer_obj, GtkCList *list); #define CLIST_FROM_SW(obj) (GTK_CLIST(GTK_SCROLLED_WINDOW (obj)->container.child)) JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkListPeer_create (JNIEnv *env, jobject obj) { GtkWidget *list, *sw; gdk_threads_enter (); list = gtk_clist_new (1); gtk_widget_show (list); sw = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add (GTK_CONTAINER (sw), list); gdk_threads_leave (); NSA_SET_PTR (env, obj, sw); } JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkListPeer_connectHooks (JNIEnv *env, jobject obj) { void *ptr; ptr = NSA_GET_PTR (env, obj); gdk_threads_enter (); gtk_widget_realize (GTK_WIDGET (ptr)); connect_selectable_hook (env, obj, CLIST_FROM_SW (ptr)); connect_awt_hook (env, obj, 1, GTK_WIDGET (ptr)->window); gdk_threads_leave (); } JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkListPeer_append (JNIEnv *env, jobject obj, jobjectArray items) { void *ptr; GtkCList *list; jint count, i; ptr = NSA_GET_PTR (env, obj); count = (*env)->GetArrayLength (env, items); gdk_threads_enter (); list = CLIST_FROM_SW (ptr); for (i = 0; i < count; i++) { const char *text; jobject item; item = (*env)->GetObjectArrayElement (env, items, i); text = (*env)->GetStringUTFChars (env, item, NULL); gtk_clist_append (list, (char **)&text); (*env)->ReleaseStringUTFChars (env, item, text); } gtk_clist_columns_autosize (list); gdk_threads_leave (); } JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkListPeer_old_create (JNIEnv *env, jobject obj, jobject parent_obj, jobjectArray items, jboolean mode) { GtkWidget *list, *sw, *parent; jsize count, i; parent = NSA_GET_PTR (env, parent_obj); count = (*env)->GetArrayLength (env, items); gdk_threads_enter (); list = gtk_clist_new (1); gtk_widget_show (list); sw = gtk_scrolled_window_new (NULL, NULL); set_parent (sw, GTK_CONTAINER (parent)); gtk_widget_realize (sw); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add (GTK_CONTAINER (sw), list); connect_selectable_hook (env, obj, GTK_CLIST (list)); connect_awt_hook (env, obj, 1, list->window); gtk_clist_set_selection_mode (GTK_CLIST (list), mode ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE); for (i = 0; i < count; i++) { const char *text; jobject item; item = (*env)->GetObjectArrayElement (env, items, i); text = (*env)->GetStringUTFChars (env, item, NULL); gtk_clist_append (GTK_CLIST (list), (char **)&text); (*env)->ReleaseStringUTFChars (env, item, text); } gtk_clist_columns_autosize (GTK_CLIST (list)); gdk_threads_leave (); NSA_SET_PTR (env, obj, sw); } JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkListPeer_add (JNIEnv *env, jobject obj, jstring text, jint index) { void *ptr; const char *str; ptr = NSA_GET_PTR (env, obj); str = (*env)->GetStringUTFChars (env, text, NULL); gdk_threads_enter (); gtk_clist_insert (CLIST_FROM_SW (ptr), index, (char **)&str); gdk_threads_leave (); (*env)->ReleaseStringUTFChars (env, text, str); } JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkListPeer_delItems (JNIEnv *env, jobject obj, jint start, jint end) { void *ptr; GtkCList *list; jint i; ptr = NSA_GET_PTR (env, obj); gdk_threads_enter (); list = CLIST_FROM_SW (ptr); if (end == -1) /* special case for removing all rows */ end = list->rows; gtk_clist_freeze (list); for (i = start; i < end; i++) gtk_clist_remove (list, i); gtk_clist_thaw (list); gdk_threads_leave (); } JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkListPeer_select (JNIEnv *env, jobject obj, jint index) { void *ptr; ptr = NSA_GET_PTR (env, obj); gdk_threads_enter (); gtk_clist_select_row (CLIST_FROM_SW (ptr), index, 0); gdk_threads_leave (); } JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkListPeer_deselect (JNIEnv *env, jobject obj, jint index) { void *ptr; ptr = NSA_GET_PTR (env, obj); gdk_threads_enter (); gtk_clist_unselect_row (CLIST_FROM_SW (ptr), index, 0); gdk_threads_leave (); } /* FIXME: magic mojo (that doesn't seem to do anything) */ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkListPeer_getSize (JNIEnv *env, jobject obj, jint rows, jintArray jdims) { void *ptr; jint *dims; GtkWidget *list; GtkScrolledWindow *sw; GtkRequisition myreq; dims = (*env)->GetIntArrayElements (env, jdims, NULL); dims[0] = dims[1] = 0; if (rows < 3) rows = 3; ptr = NSA_GET_PTR (env, obj); gdk_threads_enter (); list = GTK_WIDGET (CLIST_FROM_SW (ptr)); sw = GTK_SCROLLED_WINDOW (ptr); /* gtk_widget_size_request(GTK_WIDGET (GTK_SCROLLED_WINDOW(sw)->hscrollbar), &myreq); dims[1]=myreq.height+GTK_SCROLLED_WINDOW_CLASS (GTK_OBJECT (sw)->klass)->scrollbar_spacing; */ gtk_signal_emit_by_name (GTK_OBJECT (GTK_SCROLLED_WINDOW(sw)->vscrollbar), "size_request", &myreq); /* gtk_widget_size_request(GTK_WIDGET (GTK_SCROLLED_WINDOW(sw)->vscrollbar), &myreq); */ dims[0]=myreq.width+GTK_SCROLLED_WINDOW_CLASS (GTK_OBJECT (sw)->klass)->scrollbar_spacing; gtk_signal_emit_by_name (GTK_OBJECT (list), "size_request", &myreq); // gtk_widget_size_request(GTK_WIDGET (list), &myreq); dims[0] += myreq.width + gdk_char_width (list->style->font, 'W'); dims[1] += ((rows * (gdk_char_height (list->style->font, 'W')+7)) + (2 * (list->style->klass->ythickness))); gdk_threads_leave (); (*env)->ReleaseIntArrayElements (env, jdims, dims, 0); } JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_gtk_GtkListPeer_getSelectedIndexes (JNIEnv *env, jobject obj) { void *ptr; GtkCList *list; jintArray selection; jint *sel; GList *child; jint count, i; ptr = NSA_GET_PTR (env, obj); gdk_threads_enter (); list = CLIST_FROM_SW (ptr); count = g_list_length (list->selection); selection = (*env)->NewIntArray (env, count); sel = (*env)->GetIntArrayElements (env, selection, NULL); for (i = 0, child = list->selection; i < count; i++) { sel[i] = GPOINTER_TO_INT (child->data); child = g_list_next (child); } gdk_threads_leave (); (*env)->ReleaseIntArrayElements (env, selection, sel, 0); return selection; } JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkListPeer_makeVisible (JNIEnv *env, jobject obj, jint index) { void *ptr; ptr = NSA_GET_PTR (env, obj); gdk_threads_enter (); gtk_clist_moveto (CLIST_FROM_SW (ptr), index, 0, 0.5, 0.5); gdk_threads_leave (); } JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkListPeer_setMultipleMode (JNIEnv *env, jobject obj, jboolean mode) { void *ptr; ptr = NSA_GET_PTR (env, obj); gdk_threads_enter (); gtk_clist_set_selection_mode (CLIST_FROM_SW (ptr), mode ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE); gdk_threads_leave (); } static void item_select (GtkCList *list, int row, int col, GdkEventButton *event, jobject *peer_obj) { (*gdk_env)->CallVoidMethod (gdk_env, *peer_obj, postListItemEventID, row, (jint) AWT_ITEM_SELECTED); } static void item_unselect (GtkCList *list, int row, int col, GdkEventButton *event, jobject *peer_obj) { (*gdk_env)->CallVoidMethod (gdk_env, *peer_obj, postListItemEventID, row, (jint) AWT_ITEM_DESELECTED); } static void connect_selectable_hook (JNIEnv *env, jobject peer_obj, GtkCList *list) { jobject *obj; obj = (jobject *) malloc (sizeof (jobject)); *obj = (*env)->NewGlobalRef (env, peer_obj); gtk_signal_connect (GTK_OBJECT (list), "select_row", GTK_SIGNAL_FUNC (item_select), obj); gtk_signal_connect (GTK_OBJECT (list), "unselect_row", GTK_SIGNAL_FUNC (item_unselect), obj); }