]> granicus.if.org Git - nethack/commitdiff
debian bug #154629 - extended commands in gnome front end
authorcohrs <cohrs>
Wed, 15 Oct 2003 06:02:27 +0000 (06:02 +0000)
committercohrs <cohrs>
Wed, 15 Oct 2003 06:02:27 +0000 (06:02 +0000)
Not all of the extended commands worked in the gnome interface because
'#' just caused the next character to be treated as a meta character (this
was a hack I added a while back when none of the extended commands worked).
Resolved by finally adding an extended command menu to the gnome interface.
- updated some formatting so I could read the code
- fixed startup player selection menus so accelerators work
- added necessary calls to make sure selected menu item is visible
- also removed some dead code

doc/fixes34.3
win/gnome/gnbind.c
win/gnome/gnmenu.c
win/gnome/gnmenu.h
win/gnome/gnopts.c
win/gnome/gnplayer.c
win/gnome/gnsignal.c

index e0f32a445de454f5be3bff93a884825df97759ed..b16b221b78c8e2a7f0b2bf5e6c742ac2042ef8c2 100644 (file)
@@ -63,6 +63,7 @@ X11: avoid a possible crash when using window manger to close a player
        selection window
 Gnome: add Quiver menu item, fix outdated Quit menu item
 Gnome: key values on unsigned char platform could fail to compare correctly
+Gnome: real extended command menu so all extended commands can be entered
 tty: avoid crash displaying quit inventory if inventory was already displayed
 
 
index 51829bb515fa3097adc27fef15843c362caf944e..cb9c29f2ea19ca6b405e624b98dc6a608ce0d7a7 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "gnbind.h"
 #include "gnmain.h"
+#include "gnmenu.h"
 #include "gnaskstr.h"
 #include "gnyesno.h"
 
@@ -1098,7 +1099,7 @@ int get_ext_cmd(void)
 */
 int gnome_get_ext_cmd()
 {
-    return -1;
+    return ghack_menu_ext_cmd();
 }
 
 
index 4536401be2fd70f4c8a85c4557b6a81b69bf6293..4462f40ed66507cecdceeaf07186b199375a74b7 100644 (file)
@@ -8,6 +8,7 @@
 #include "gnmenu.h"
 #include "gnmain.h"
 #include "gnbind.h"
+#include "func_tab.h"
 
 typedef enum {
        MenuUnknown = 0,
@@ -22,65 +23,60 @@ typedef struct {
        int selected;
 } menuItem;
 
+typedef struct {
+       int curItem;
+       int numRows;
+       int charIdx;
+       guint32 lastTime;
+} extMenu;
 
 static GdkColor color_blue = { 0, 0, 0, 0xffff };
 
 
-void ghack_menu_window_key_press(GtkWidget *menuWin, GdkEventKey *event, 
-       gpointer data)
+static void
+ghack_menu_window_key(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;
-                               }
-                       }
+    int i, numRows;
+    menuItem* item;
+    MenuWinType isMenu;
+
+    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) {
+                   gtk_clist_unselect_row( GTK_CLIST (clist),
+                                           item->itemNumber, 0);
+                   item->selected = FALSE;
+               } else {
+                   gtk_clist_select_row(GTK_CLIST (clist),
+                                        item->itemNumber, 0);
+                   if (gtk_clist_row_is_visible(GTK_CLIST(clist),
+                               item->itemNumber) != GTK_VISIBILITY_FULL)
+                       gtk_clist_moveto(GTK_CLIST(clist),
+                                        item->itemNumber, 0, 0.5, 0);
+                   item->selected = TRUE;
                }
+           }
        }
+    }
 }
 
 
@@ -240,22 +236,6 @@ ghack_menu_window_select_menu (GtkWidget *menuWin,
                       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)) {
@@ -368,9 +348,7 @@ ghack_menu_window_add_menu( GtkWidget *menuWin, gpointer menu_item,
                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!");
+               } else {
                    accelBuf[0] = buf[0] = 0;
                }
                g_snprintf(buf, sizeof(buf), "%s", item->str);
@@ -641,7 +619,7 @@ ghack_init_menu_window (void)
                        NULL);
 
     gtk_signal_connect(GTK_OBJECT(menuWin), "key_press_event",
-                       GTK_SIGNAL_FUNC(ghack_menu_window_key_press),
+                       GTK_SIGNAL_FUNC(ghack_menu_window_key),
                        NULL);
 
     /* Center the dialog over parent */
@@ -654,3 +632,124 @@ ghack_init_menu_window (void)
     return menuWin;
 }
 
+static void
+ghack_ext_key_hit(GtkWidget *menuWin, GdkEventKey *event, gpointer data)
+{
+    GtkWidget* clist;
+    extMenu* info = (extMenu*) data;
+    int i;
+    char c = event->string[0];
+
+    clist = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(menuWin), "clist"));
+    g_assert(clist != NULL);
+
+    /* if too long between keystrokes, reset to initial state */
+    if (event->time - info->lastTime > 500) goto init_state;
+
+    /* see if current item continue to match */
+    if (info->charIdx > 0) {
+       if (extcmdlist[info->curItem].ef_txt[info->charIdx] == c) {
+           ++info->charIdx;
+           goto found;
+       }
+    }
+
+    /* see if the prefix matches a later command in the list */
+    if (info->curItem >= 0) {
+       for (i = info->curItem + 1; i < info->numRows; ++i) {
+           if (!strncmp(extcmdlist[info->curItem].ef_txt,
+                        extcmdlist[i].ef_txt, info->charIdx-1)) {
+               if (extcmdlist[i].ef_txt[info->charIdx] == c) {
+                   ++info->charIdx;
+                   info->curItem = i;
+                   goto found;
+               }
+           }
+       }
+    }
+               
+init_state:
+    /* reset to initial state, look for matching 1st character */
+    for (i = 0; i < info->numRows; ++i) {
+       if (extcmdlist[i].ef_txt[0] == c) {
+           info->charIdx = 1;
+           info->curItem = i;
+           goto found;
+       }
+    }
+
+    /* no match: leave prior, if any selection in place */
+    return;
+
+found:
+    info->lastTime = event->time;
+    gtk_clist_select_row(GTK_CLIST(clist), info->curItem, 0);
+    if (gtk_clist_row_is_visible(GTK_CLIST(clist),
+                                info->curItem) != GTK_VISIBILITY_FULL)
+       gtk_clist_moveto(GTK_CLIST(clist), info->curItem, 0, 0.5, 0);
+}
+
+int
+ghack_menu_ext_cmd(void)
+{
+    int n;
+    GtkWidget* dialog;
+    GtkWidget* swin;
+    GtkWidget* frame1;
+    GtkWidget* clist;
+    extMenu info;
+
+    dialog = gnome_dialog_new("Extended Commands",
+                             GNOME_STOCK_BUTTON_OK,
+                             GNOME_STOCK_BUTTON_CANCEL,
+                             NULL);
+    gnome_dialog_close_hides(GNOME_DIALOG(dialog), FALSE);
+    gtk_signal_connect(GTK_OBJECT(dialog), "key_press_event",
+                      GTK_SIGNAL_FUNC(ghack_ext_key_hit), &info);
+
+    frame1 = gtk_frame_new("Make your selection");
+    gtk_object_set_data(GTK_OBJECT(dialog), "frame1", frame1);
+    gtk_widget_show(frame1);
+    gtk_container_border_width(GTK_CONTAINER(frame1), 3);
+
+    swin = gtk_scrolled_window_new(NULL, NULL);
+    clist = gtk_clist_new(2);
+    gtk_object_set_data(GTK_OBJECT(dialog), "clist", clist);
+    gtk_widget_set_usize(clist, 500, 400);
+    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_container_add(GTK_CONTAINER(frame1), swin);
+    gtk_box_pack_start_defaults(GTK_BOX(GNOME_DIALOG(dialog)->vbox), frame1);
+
+    /* Add the extended commands into the list here... */
+    for (n = 0; extcmdlist[n].ef_txt; ++n) {
+       const char *text[3]={extcmdlist[n].ef_txt,extcmdlist[n].ef_desc,NULL};
+       gtk_clist_insert(GTK_CLIST(clist), n, (char**) text);
+    }
+
+    /* fill in starting info fields */
+    info.curItem = -1;
+    info.numRows = n;
+    info.charIdx = 0;
+    info.lastTime = 0;
+
+    gtk_clist_columns_autosize(GTK_CLIST(clist));
+    gtk_widget_show_all(swin);
+
+    /* Center the dialog over over parent */
+    gnome_dialog_set_default(GNOME_DIALOG(dialog), 0);
+    gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
+    gnome_dialog_set_parent(GNOME_DIALOG(dialog),
+                           GTK_WINDOW(ghack_get_main_window()));
+
+    /* Run the dialog -- returning whichever button was pressed */
+    n = gnome_dialog_run_and_close(GNOME_DIALOG(dialog));
+
+    /* Quit on button 2 or error */
+    return (n != 0) ? -1 : info.curItem;
+}
index 2864cc709f93e668083069b4685f8e6c8ad588e3..7055aa4a9cac2be0a386f3a9230a86d911a43a8b 100644 (file)
@@ -27,6 +27,6 @@ typedef struct _GHackMenuItem GHackMenuItem;
 
 int ghack_menu_window_select_menu (GtkWidget *menuWin, 
        MENU_ITEM_P **_selected, gint how);
-
+int ghack_menu_ext_cmd(void);
 
 #endif  /* GnomeHackMenuWindow_h */
index b4845b965ddd5946c4d180db36803c6a503b845e..04d0073be5745ca652c84cf5e5c2c445f8a93479 100644 (file)
@@ -15,7 +15,7 @@ static GtkWidget* clist;
 const char* tilesets[] = { "Traditional (16x16)", "Big (32x32)", 0 };
 
 static void
-player_sel_key_hit (GtkWidget *widget, GdkEventKey *event, gpointer data)
+opt_sel_key_hit(GtkWidget *widget, GdkEventKey *event, gpointer data)
 {
       int i;
       for (i = 0; tilesets[i] != 0; ++i) {
@@ -27,7 +27,7 @@ player_sel_key_hit (GtkWidget *widget, GdkEventKey *event, gpointer data)
 }
 
 static void
-player_sel_row_selected (GtkCList *cList, int row, int col, GdkEvent *event)
+opt_sel_row_selected(GtkCList *cList, int row, int col, GdkEvent *event)
 {
     tileset = row;
 }
@@ -46,7 +46,7 @@ ghack_settings_dialog()
                            NULL);
     gnome_dialog_close_hides (GNOME_DIALOG (dialog), FALSE);
     gtk_signal_connect (GTK_OBJECT (dialog), "key_press_event",
-                     GTK_SIGNAL_FUNC (player_sel_key_hit), tilesets );
+                     GTK_SIGNAL_FUNC (opt_sel_key_hit), tilesets );
 
     frame1 = gtk_frame_new (_("Choose one of the following tilesets:"));
     gtk_object_set_data (GTK_OBJECT (dialog), "frame1", frame1);
@@ -62,7 +62,7 @@ ghack_settings_dialog()
            GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
     gtk_signal_connect (GTK_OBJECT (clist), "select_row",
-                       GTK_SIGNAL_FUNC (player_sel_row_selected), NULL );
+                       GTK_SIGNAL_FUNC (opt_sel_row_selected), NULL );
 
     gtk_container_add (GTK_CONTAINER (frame1), swin);
     gtk_box_pack_start_defaults (GTK_BOX (GNOME_DIALOG (dialog)->vbox), frame1);
index f34fa506a2812c8cd7f4cc5eedc7952b1c9dabae..f10fcd2add8e6431dc397668603d645a48b99aa6 100644 (file)
@@ -8,21 +8,24 @@
 #include "gnmain.h"
 #include "hack.h"
 
-static gint role_number;                                                      
-static GtkWidget* clist;                                                      
-                                                                              
-static void                                                                   
-player_sel_key_hit (GtkWidget *widget, GdkEventKey *event, gpointer data)     
+static gint role_number;
+static GtkWidget* clist;
+
+static void
+player_sel_key_hit (GtkWidget *widget, GdkEventKey *event, gpointer data)
 {
-    const char** roles = data;                                              
-    int i;                                                                  
-    for (i = 0; roles[i] != 0; ++i) {                                       
-       if (roles[i][0] == toupper(event->keyval)) {                    
-           role_number = i;                                        
-           gtk_clist_select_row( GTK_CLIST (clist), i, 0);         
-       }                                                               
-    }                                                                       
-}                                                                             
+    const char** roles = data;
+    int i;
+    for (i = 0; roles[i] != 0; ++i) {
+       if (tolower(roles[i][0]) == tolower(event->keyval)) {
+           role_number = i;
+           gtk_clist_select_row( GTK_CLIST (clist), i, 0);
+           if (gtk_clist_row_is_visible(GTK_CLIST(clist),
+                                        i) != GTK_VISIBILITY_FULL)
+               gtk_clist_moveto(GTK_CLIST(clist), i, 0, 0.5, 0);
+       }
+    }
+}
 
 static void
 player_sel_row_selected (GtkCList *clist, int row, int col, GdkEvent *event)
@@ -46,8 +49,8 @@ ghack_player_sel_dialog(const char** choices,
                            GNOME_STOCK_BUTTON_CANCEL,
                            NULL);
     gnome_dialog_close_hides (GNOME_DIALOG (dialog), FALSE);
-    gtk_signal_connect (GTK_OBJECT (dialog), "key_press_event",               
-                      GTK_SIGNAL_FUNC (player_sel_key_hit), choices );          
+    gtk_signal_connect (GTK_OBJECT (dialog), "key_press_event",
+                      GTK_SIGNAL_FUNC (player_sel_key_hit), choices );
 
     frame1 = gtk_frame_new(prompt);
     gtk_object_set_data (GTK_OBJECT (dialog), "frame1", frame1);
@@ -67,7 +70,7 @@ ghack_player_sel_dialog(const char** choices,
 
     gtk_container_add (GTK_CONTAINER (frame1), swin);
     gtk_box_pack_start_defaults (GTK_BOX (GNOME_DIALOG (dialog)->vbox), frame1);
+
     /* Add the roles into the list here... */
     for (i=0; choices[i]; i++) {
            gchar accelBuf[BUFSZ];
@@ -75,19 +78,18 @@ ghack_player_sel_dialog(const char** choices,
            sprintf( accelBuf, "%c ", tolower(choices[i][0]));
            gtk_clist_insert (GTK_CLIST (clist), i, (char**)text);
     }
+
     gtk_clist_columns_autosize (GTK_CLIST (clist));
     gtk_widget_show_all (swin);
 
     /* Center the dialog over over parent */
     gnome_dialog_set_default( GNOME_DIALOG(dialog), 0);
     gtk_window_set_modal( GTK_WINDOW(dialog), TRUE);
-    gnome_dialog_set_parent (GNOME_DIALOG (dialog), 
+    gnome_dialog_set_parent (GNOME_DIALOG (dialog),
            GTK_WINDOW (ghack_get_main_window ()) );
 
     /* Run the dialog -- returning whichever button was pressed */
-    i = gnome_dialog_run (GNOME_DIALOG (dialog));
-    gnome_dialog_close (GNOME_DIALOG (dialog));
+    i = gnome_dialog_run_and_close(GNOME_DIALOG(dialog));
 
     /* Quit on button 2 or error */
     if (i < 0  || i > 1) {
index 0387975843e1bc6a9b0ab0608eb4f0834ef16457..2e5b621675269f88e59b9ad19853aa22001a8257 100644 (file)
@@ -369,8 +369,8 @@ ghack_handle_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data)
 
        /* can't just ignore "#", it's a core feature */
     case GDK_numbersign:
-       was_pound = 1;
-       return;
+       key='#';
+       break;
 
        /* We will probably want to do something with these later... */
     case GDK_KP_Begin:
@@ -416,6 +416,7 @@ ghack_handle_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data)
 
     default:
        key = event->keyval;
+       break;
     }
 
     if ((event->state & alt) || was_pound) {