From: jwalz Date: Sat, 5 Jan 2002 21:06:01 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: MOVE2GIT~3607 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ac1fdd4511b1f11bb73996993c20092a74125bdc;p=nethack *** empty log message *** --- diff --git a/win/gnome/gnmenu.c b/win/gnome/gnmenu.c new file mode 100644 index 000000000..133c96ac5 --- /dev/null +++ b/win/gnome/gnmenu.c @@ -0,0 +1,656 @@ +/* SCCS Id: @(#)gnmenu.c 3.3 2000/07/16 */ +/* Copyright (C) 1998 by Erik Andersen */ +/* NetHack may be freely redistributed. See license for details. */ + +#include +#include +#include +#include "gnmenu.h" +#include "gnmain.h" +#include "gnbind.h" + +typedef enum { + MenuUnknown = 0, + MenuText, + MenuMenu +} MenuWinType; + +typedef struct { + ANY_P identifier; + gchar accelerator[BUFSZ]; + int itemNumber; + int selected; +} menuItem; + + +static GdkColor color_blue = { 0, 0, 0, 0xffff }; + + +void ghack_menu_window_key_press(GtkWidget *menuWin, GdkEventKey *event, + gpointer data) +{ + int i, numRows; + menuItem* item; + MenuWinType isMenu; + + /* Turn this on to debug key events */ +#if 0 + int ctl=GDK_CONTROL_MASK; + int alt=GDK_MOD1_MASK; + + g_message("I got a \"%s\" key (%d) %s%s", + gdk_keyval_name (event->keyval), event->keyval, + (event->state&ctl)? "+CONTROL":"", + (event->state&alt)? "+ALT":""); +#endif + + isMenu = (MenuWinType) GPOINTER_TO_INT + (gtk_object_get_data (GTK_OBJECT (menuWin), "isMenu")); + + if (isMenu == MenuMenu) { + GtkWidget *clist; + gint selection_mode; + + clist = GTK_WIDGET(gtk_object_get_data (GTK_OBJECT (menuWin), "clist")); + g_assert (clist != NULL); + numRows = GPOINTER_TO_INT( gtk_object_get_data( + GTK_OBJECT(clist), "numRows") ); + selection_mode = GPOINTER_TO_INT( gtk_object_get_data + (GTK_OBJECT (clist), "selection_mode")); + for( i=0; i<=numRows; i++) { + item = (menuItem*) gtk_clist_get_row_data( + GTK_CLIST (clist), i); + if (item == NULL) + continue; + if (!strcmp(item->accelerator, "")) { + continue; + } + if ( (!strcmp(item->accelerator, event->string)) || + ((selection_mode == GTK_SELECTION_MULTIPLE) && + (event->keyval == ','))) { + if (item->selected==TRUE) { + gtk_clist_unselect_row( GTK_CLIST (clist), + item->itemNumber, 0); + item->selected=FALSE; + } + else { + gtk_clist_select_row( GTK_CLIST (clist), + item->itemNumber, 0); + item->selected=TRUE; + } + } + } + } +} + + +static void +ghack_menu_row_selected (GtkCList *clist, int row, int col, GdkEvent *event) +{ + /* FIXME: Do something */ +} + + +void +ghack_menu_window_clear(GtkWidget *menuWin, gpointer data) +{ + MenuWinType isMenu; + int i, numRows; + menuItem* item; + + isMenu = (MenuWinType) GPOINTER_TO_INT + (gtk_object_get_data (GTK_OBJECT (menuWin), "isMenu")); + + if (isMenu == MenuMenu) { + GtkWidget *clist; + + clist = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (menuWin), "clist")); + g_assert (clist != NULL); + + /* destroy existing menu data, if any */ + if (clist) { + /* destroy all the row_data we stored in the clist */ + numRows = GPOINTER_TO_INT( gtk_object_get_data( + GTK_OBJECT(clist), "numRows") ); + for( i=0; itext), 0, 0); + } + +} + +void +ghack_menu_window_display(GtkWidget *menuWin, gboolean blocking, + gpointer data) +{ + //if(blocking) { + gnome_dialog_close_hides (GNOME_DIALOG (menuWin), TRUE); + gnome_dialog_set_close (GNOME_DIALOG (menuWin), TRUE); + gnome_dialog_run_and_close(GNOME_DIALOG (menuWin)); + //} + //else { + //gtk_widget_show(menuWin); + //} +} + +gint +ghack_menu_hide( GtkWidget *menuWin, GdkEvent *event, gpointer data ) +{ + gtk_widget_hide (menuWin); + return FALSE; /* FIXME: what is correct result here? */ +} + + +void +ghack_menu_window_start_menu (GtkWidget *menuWin, gpointer data) +{ + GtkWidget *frame1, *swin, *clist; + MenuWinType isMenu; + + g_assert (menuWin != NULL); + g_assert (data == NULL); + + /* destroy existing menu data, if any */ + frame1 = gtk_object_get_data (GTK_OBJECT (menuWin), "frame1"); + if (frame1) + gtk_widget_destroy (frame1); + + isMenu = MenuMenu; + gtk_object_set_data (GTK_OBJECT (menuWin), "isMenu", + GINT_TO_POINTER (isMenu)); + + gtk_widget_set_usize (GTK_WIDGET (menuWin), 500, 400); + gtk_window_set_policy (GTK_WINDOW (menuWin), TRUE, TRUE, FALSE); + + frame1 = gtk_frame_new ("Make your selection"); + g_assert (frame1 != NULL); + gtk_object_set_data (GTK_OBJECT(menuWin), "frame1", frame1); + gtk_widget_show (GTK_WIDGET (frame1)); + gtk_container_set_border_width (GTK_CONTAINER (frame1), 5); + gtk_box_pack_start (GTK_BOX (GNOME_DIALOG(menuWin)->vbox), frame1, + TRUE, TRUE, 0); + + swin = gtk_scrolled_window_new (NULL, NULL); + g_assert (swin != NULL); + gtk_object_set_data (GTK_OBJECT(menuWin), "swin", swin); + gtk_widget_show (GTK_WIDGET (swin)); + gtk_container_add (GTK_CONTAINER (frame1), swin); + + clist = gtk_clist_new (4); + g_assert (clist != NULL); + gtk_object_set_data (GTK_OBJECT(menuWin), "clist", clist); + gtk_widget_show (GTK_WIDGET (clist)); + gtk_container_add (GTK_CONTAINER (swin), clist); + + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swin), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + + gtk_signal_connect (GTK_OBJECT (clist), "select_row", + GTK_SIGNAL_FUNC (ghack_menu_row_selected), NULL); + gtk_object_set_data (GTK_OBJECT (clist), "numItems", + GINT_TO_POINTER (-1)); +} + + +int +ghack_menu_window_select_menu (GtkWidget *menuWin, + MENU_ITEM_P **_selected, gint how) +{ + gint rc; + guint num_sel, i, idx; + GtkWidget *clist; + GList *cur; + MENU_ITEM_P *selected = NULL; + menuItem* item; + + g_assert (_selected != NULL); + *_selected = NULL; + + + if (how == PICK_NONE) { + gnome_dialog_close_hides (GNOME_DIALOG (menuWin), TRUE); + rc = gnome_dialog_run_and_close (GNOME_DIALOG (menuWin)); + return( rc == 1 ? -1 : 0); + } + + clist = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (menuWin), "clist")); + g_assert (clist != NULL); + + gtk_object_set_data (GTK_OBJECT (clist), "selection_mode", + GINT_TO_POINTER ((how == PICK_ANY)? + GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE)); + gtk_clist_set_selection_mode (GTK_CLIST (clist), + (how == PICK_ANY)? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE); +#if 0 + /* Turn this on, and an "All" button will be appended to the + * menu dialog when it is in SELECTION_MULTIPLE mode. I commented + * this out because 1) it doesn't work very well, and 2) it is ugly. + * A better job of doing this is very welcome.... + * -Erik */ + if (how == PICK_ANY) { + static GdkEventKey event; + event.keyval='\''; + event.state=0; + gnome_dialog_append_button( GNOME_DIALOG(menuWin), "All"); + gnome_dialog_button_connect( GNOME_DIALOG(menuWin), 2, + GTK_SIGNAL_FUNC(ghack_menu_window_key_press), + &event); + } +#endif + gnome_dialog_close_hides (GNOME_DIALOG (menuWin), TRUE); + rc = gnome_dialog_run_and_close (GNOME_DIALOG (menuWin)); + if ((rc == 1) || (GTK_CLIST (clist)->selection == NULL)) { + return(-1); + } + + num_sel = g_list_length (GTK_CLIST (clist)->selection); + if (num_sel < 1) { + return(-1); + } + + /* fill in array with selections from clist */ + selected = g_new0( MENU_ITEM_P, num_sel); + g_assert (selected != NULL); + cur = GTK_CLIST (clist)->selection; + i = 0; + while (cur) { + g_assert (i < num_sel); + + /* grab row number from clist selection list */ + idx = GPOINTER_TO_INT (cur->data); + + item = (menuItem*) gtk_clist_get_row_data( GTK_CLIST (clist), idx); + selected[i].item = item->identifier; + selected[i].count = -1; + cur = g_list_next(cur); + i++; + } + + *_selected = selected; + + return( (int) num_sel); +} + +void +ghack_menu_window_add_menu( GtkWidget *menuWin, gpointer menu_item, + gpointer data) +{ + GHackMenuItem* item; + GtkWidget *clist; + gchar buf[BUFSZ]="", accelBuf[BUFSZ]=""; + gchar *pbuf; + char *text[4] = { buf, NULL, NULL, NULL }; + gint nCurrentRow = -1, numItems = -1; + MenuWinType isMenu; + GtkStyle *bigStyle = NULL; + gboolean item_selectable; + GdkImlibImage* image; + static gboolean special; + + g_assert (menu_item != NULL); + item = (GHackMenuItem*) menu_item; + item_selectable = ( item->identifier->a_int == 0)? FALSE : TRUE; + isMenu = (MenuWinType) GPOINTER_TO_INT + (gtk_object_get_data (GTK_OBJECT (menuWin), "isMenu")); + + clist = GTK_WIDGET (gtk_object_get_data (GTK_OBJECT (menuWin), "clist")); + g_assert (clist != NULL); + /* This is a special kludge to make the special hidden help menu item work as designed */ + if ( special==TRUE ) { + special=FALSE; + item_selectable=TRUE; + } + if ( ! strcmp( item->str, "The NetHack license.")) { + special=TRUE; + } + + if (item->str) { + + /* First, make a new blank entry in the clist */ + nCurrentRow = gtk_clist_append (GTK_CLIST (clist), text); + + if (item->glyph != NO_GLYPH) { + image = ghack_image_from_glyph( item->glyph, FALSE); + if (image==NULL || image->pixmap==NULL) { + g_warning("Bummer -- having to force rendering for glyph %d!", item->glyph); + /* wierd -- pixmap is NULL so retry rendering it */ + image = ghack_image_from_glyph( item->glyph, TRUE); + } + if (image==NULL || image->pixmap==NULL) { + g_error("Aiiee! glyph is still NULL for item\n\"%s\"", + item->str); + } + else + gtk_clist_set_pixmap (GTK_CLIST (clist), + nCurrentRow, 1, + gdk_imlib_move_image( image), + gdk_imlib_move_mask( image)); + } + if (item->accelerator) { + /* FIXME: handle accelerator, */ + g_snprintf(accelBuf, sizeof(accelBuf), "%c ", item->accelerator); + gtk_clist_set_text (GTK_CLIST (clist), nCurrentRow, 0, accelBuf); + g_snprintf(buf, sizeof(buf), "%s", item->str); + gtk_clist_set_text (GTK_CLIST (clist), nCurrentRow, 2, buf); + } else { + if (item->group_accel) { + /* FIXME: maybe some day I should try to handle + * group accelerators... */ + } + if (( (item->attr == 0) && (item->identifier->a_int != 0)) || (special ==TRUE) ) { + numItems = GPOINTER_TO_INT( gtk_object_get_data( + GTK_OBJECT(clist), "numItems") )+1; + + /* Ok, now invent a unique accelerator */ + if ( ('a'+numItems) <= 'z' ) { + g_snprintf(accelBuf, sizeof(accelBuf), "%c ", 'a'+numItems); + gtk_clist_set_text(GTK_CLIST(clist), nCurrentRow, 0, accelBuf); + } + else if ( ('A'+numItems-26)<='Z') { + g_snprintf(accelBuf, sizeof(accelBuf), "%c ", 'A'+numItems-26); + gtk_clist_set_text(GTK_CLIST(clist), nCurrentRow, 0, accelBuf); + } + else { + g_warning( "I've run out of accelerator letters!"); + accelBuf[0] = buf[0] = 0; + } + g_snprintf(buf, sizeof(buf), "%s", item->str); + gtk_clist_set_text (GTK_CLIST (clist), nCurrentRow, 2, buf); + gtk_object_set_data (GTK_OBJECT (clist), "numItems", + GINT_TO_POINTER (numItems)); + + /* This junk is to specially handle the options menu */ + pbuf = strstr( buf, " ["); + if (pbuf == NULL) { + pbuf = strstr( buf, "\t["); + } + if (pbuf != NULL) { + *pbuf=0; + pbuf++; + gtk_clist_set_text (GTK_CLIST (clist), nCurrentRow, 3, pbuf); + } + } + /* FIXME: handle more than 26*2 accelerators (but how? + * since I only have so many keys to work with???) + else + { + foo(); + } + */ + else { + g_snprintf(buf, sizeof(buf), "%s", item->str); + pbuf = strstr( buf, " ["); + if (pbuf == NULL) { + pbuf = strstr( buf, "\t["); + } + if (pbuf != NULL) { + *pbuf=0; + pbuf++; + gtk_clist_set_text (GTK_CLIST (clist), nCurrentRow, 3, pbuf); + } + gtk_clist_set_text (GTK_CLIST (clist), nCurrentRow, 2, buf); + + } + } + + if (item->attr) { + switch(item->attr) { + case ATR_ULINE: + case ATR_BOLD: + case ATR_BLINK: + case ATR_INVERSE: + bigStyle = gtk_style_copy (GTK_WIDGET (clist)->style); + g_assert (bigStyle != NULL); + gdk_font_unref (bigStyle->font); + bigStyle->font = gdk_font_load ( + "-misc-fixed-*-*-*-*-20-*-*-*-*-*-*-*"); + bigStyle->fg[GTK_STATE_NORMAL] = color_blue; + gtk_clist_set_cell_style (GTK_CLIST (clist), + nCurrentRow, 2, bigStyle); + item_selectable = FALSE; + } + } + + + g_assert (nCurrentRow >= 0); + gtk_clist_set_selectable (GTK_CLIST (clist), nCurrentRow, + item_selectable); + + if ( item_selectable==TRUE && item->presel== TRUE) { + /* pre-select this item */ + gtk_clist_select_row( GTK_CLIST (clist), nCurrentRow, 0); + } + + gtk_object_set_data (GTK_OBJECT (clist), "numRows", + GINT_TO_POINTER (nCurrentRow)); + + /* We have to allocate memory here, since the menu_item currently + * lives on the stack, and will otherwise go to the great bit bucket + * in the sky as soon as this function exits, which would leave a + * pointer to crap in the row_data. Use g_memdup to make a private, + * persistant copy of the item identifier. + * + * We need to arrange to blow away this memory somewhere (like + * ghack_menu_destroy and ghack_menu_window_clear for example). + * + * -Erik + */ + { + menuItem newItem; + menuItem *pNewItem; + + newItem.identifier = *item->identifier; + newItem.itemNumber=nCurrentRow; + newItem.selected=FALSE; + newItem.accelerator[0]=0; + /* only copy 1 char, since accel keys are by definition 1 char */ + if (accelBuf[0]) { + strncpy(newItem.accelerator, accelBuf, 1); + } + newItem.accelerator[1]=0; + + pNewItem = g_memdup(&newItem, sizeof( menuItem)); + gtk_clist_set_row_data (GTK_CLIST (clist), nCurrentRow, + (gpointer) pNewItem); + } + } + /* Now adjust the column widths to match the contents */ + gtk_clist_columns_autosize (GTK_CLIST (clist)); +} + +void +ghack_menu_window_end_menu (GtkWidget *menuWin, gpointer data) +{ + const char* p = (const char*) data; + + if ((p) && (*p)) { + GtkWidget *frame1 = gtk_object_get_data (GTK_OBJECT (menuWin), "frame1"); + g_assert (frame1 != NULL); + + gtk_frame_set_label (GTK_FRAME(frame1), p); + } + +} + + +void ghack_menu_window_put_string(GtkWidget *menuWin, int attr, + const char* text, gpointer data) +{ + GnomeLess *gless; + MenuWinType isMenu; + + if (text == NULL) + return; + + isMenu = (MenuWinType) GPOINTER_TO_INT + (gtk_object_get_data (GTK_OBJECT (menuWin), "isMenu")); + + if (isMenu == MenuText) { + gless = GNOME_LESS (gtk_object_get_data (GTK_OBJECT (menuWin), "gless")); + g_assert (gless != NULL); + g_assert (gless->text != NULL); + g_assert (GTK_IS_TEXT (gless->text)); + + /* Don't bother with attributes yet */ + gtk_text_insert (GTK_TEXT (gless->text), NULL, NULL, NULL, text, -1); + gtk_text_insert (GTK_TEXT (gless->text), NULL, NULL, NULL, "\n", -1); + + } + + else if (isMenu == MenuUnknown) { + isMenu = MenuText; + gtk_object_set_data (GTK_OBJECT (menuWin), "isMenu", + GINT_TO_POINTER (isMenu)); + + gtk_widget_set_usize (GTK_WIDGET (menuWin), 500, 400); + gtk_window_set_policy (GTK_WINDOW (menuWin), TRUE, TRUE, FALSE); + + gless = GNOME_LESS (gnome_less_new ()); + g_assert (gless != NULL); + gtk_object_set_data (GTK_OBJECT (menuWin), "gless", gless); + gtk_widget_show (GTK_WIDGET (gless)); + + gnome_less_show_string (gless, text); + gtk_text_insert (GTK_TEXT (gless->text), NULL, NULL, NULL, "\n", -1); + + gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (menuWin)->vbox), + GTK_WIDGET (gless), TRUE, TRUE, 0); + } +} + + +void +ghack_menu_destroy (GtkWidget *menuWin, gpointer data) +{ + MenuWinType isMenu; + + isMenu = (MenuWinType) GPOINTER_TO_INT + (gtk_object_get_data (GTK_OBJECT (menuWin), "isMenu")); + + if (isMenu == MenuText) { + GnomeLess *gless; + + gless = GNOME_LESS (gtk_object_get_data (GTK_OBJECT (menuWin), "gless")); + g_assert (gless != NULL); + g_assert (gless->text != NULL); + g_assert (GTK_IS_TEXT (gless->text)); + gtk_widget_destroy(GTK_WIDGET(gless)); + } + + else if (isMenu == MenuMenu) { + GtkWidget *frame1, *swin, *clist; + + /* destroy existing menu data, if any */ + clist = gtk_object_get_data (GTK_OBJECT (menuWin), "clist"); + if (clist) { + /* destroy all the row_data we stored in the clist */ + int i, numRows; + menuItem* item; + numRows = GPOINTER_TO_INT( gtk_object_get_data( + GTK_OBJECT(clist), "numRows") ); + for( i=0; i