]> git.cworth.org Git - grrobot/commitdiff
Added keybindings/buttons for bid, pass, zap timer (nobid), and next turn
authorCarl Worth <cworth@theworths.org>
Sat, 12 Jul 2003 01:53:37 +0000 (01:53 +0000)
committerCarl Worth <cworth@theworths.org>
Sat, 12 Jul 2003 01:53:37 +0000 (01:53 +0000)
ChangeLog
src/grrobot.c

index fe019899b2b26992115bd003625a867ed8b5f434..6100bf0a654213bb45fb29f3c63222acabb5e5eb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2003-07-11  Carl Worth  <cworth@isi.edu>
+
+       * src/grrobot.c (grr_game_read_notices): Compressed move display
+       text, ('N' instead of "NORTH", etc.)
+       (grr_game_key_press_callback): Added keybindings for Next Turn,
+       Pass, Zap timer, and bids [0-9].
+       (grr_game_start_gui): Added buttons for Bid, Pass, Zap timer, Next
+       turn. Added a label for the current username.
+
 2003-07-09  Carl Worth  <cworth@isi.edu>
 
        * src/grrobot.c (grr_game_read_notices): Added support for
index a56932d5cdd23b5462908fb07970a481cf4284b5..a9a9d1e2a00a33e874e488ec6888410824cfdca4 100644 (file)
@@ -45,15 +45,27 @@ typedef struct grr_game {
 
     GtkWidget *window;
     grr_board_view_t *board_view;
-    GtkWidget *command_entry;
+    GtkWidget *message_entry;
+    GtkWidget *bid_entry;
 
     GtkTextBuffer *message_buffer;
     GtkWidget *message_view;
     int msg_id;
     int last_move_msg_id;
-    rr_robot_t last_move_robot;    
+    rr_robot_t last_move_robot;
+
+    rr_gamestate_t state;
 } grr_game_t;
 
+static void
+grr_game_pass (grr_game_t *game);
+
+static void
+grr_game_zap (grr_game_t *game);
+
+static void
+grr_game_next (grr_game_t *game);
+
 static int
 grr_game_printf (grr_game_t *game, const char *fmt, ...);
 
@@ -64,7 +76,7 @@ static int
 grr_game_print (grr_game_t *game, const char *msg);
 
 static int
-grr_game_start_gui (grr_game_t *game);
+grr_game_start_gui (grr_game_t *game, const char *user);
 
 static void
 grr_game_read_notices (grr_game_t *game);
@@ -128,7 +140,7 @@ main (int argc, char **argv)
        free (diagram);
     }
 
-    return grr_game_start_gui (&game);
+    return grr_game_start_gui (&game, args.user);
 }
 
 typedef struct _GrrNoticeSource {
@@ -210,7 +222,7 @@ grr_game_read_notices (grr_game_t *game)
            else
                fprintf (stderr, "Error during rr_client_next_notice: %s\n",
                         rr_status_str (status));
-           gtk_exit (1);
+           gtk_main_quit ();
        }
        if (!notice) {
            fprintf (stderr, "Missing notice\n");
@@ -244,10 +256,16 @@ grr_game_read_notices (grr_game_t *game)
            gtk_widget_queue_draw (GTK_WIDGET (game->window));
            break;
        case RR_NOTICE_GAMESTATE:
+           game->state = notice->u.gamestate;
            grr_game_printf (game, "\nGame state changed to: %s.",
                             rr_gamestate_str (notice->u.gamestate));
            break;
        case RR_NOTICE_TURN:
+           /* XXX: Setting game->state here is goofy. Cleaner would
+               be to make the server send a NOTICE GAMESTATE NEW
+               here. */
+           game->state = RR_GAMESTATE_NEW;
+
            grr_game_print (game, "\nNew round!");
            rr_board_set_goal_target (board, notice->u.target);
            gtk_widget_queue_draw (GTK_WIDGET (game->window));
@@ -287,13 +305,13 @@ grr_game_read_notices (grr_game_t *game)
        case RR_NOTICE_MOVE:
            if (game->msg_id == game->last_move_msg_id
                && game->last_move_robot == notice->u.move.robot) {
-               game->last_move_msg_id = grr_game_printf (game, " %s",
-                                rr_direction_str (notice->u.move.direction));
+               game->last_move_msg_id = grr_game_printf (game, ",%c",
+                                rr_direction_char (notice->u.move.direction));
            } else {
-               game->last_move_msg_id = grr_game_printf (game, "\nMove #%d: %s %s",
+               game->last_move_msg_id = grr_game_printf (game, "\nMove #%d: %s %c",
                                 notice->u.move.count,
                                 rr_robot_str (notice->u.move.robot),
-                                rr_direction_str (notice->u.move.direction));
+                                rr_direction_char (notice->u.move.direction));
                game->last_move_robot = notice->u.move.robot;
            }
            break;
@@ -339,9 +357,12 @@ grr_game_key_press_callback (GtkWidget *widget,
                             GdkEventKey *event,
                             grr_game_t *game)
 {
-    if (GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (game->command_entry))) {
+    if (GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (game->message_entry))
+       || GTK_WIDGET_HAS_FOCUS (GTK_WIDGET (game->bid_entry))
+       ) {
        if (event->keyval == GDK_Escape) {
-           gtk_entry_set_text (GTK_ENTRY (game->command_entry), "");
+           gtk_entry_set_text (GTK_ENTRY (game->message_entry), "");
+           gtk_entry_set_text (GTK_ENTRY (game->bid_entry), "");
            gtk_widget_grab_focus (GTK_WIDGET (game->message_view));
 
            return TRUE;
@@ -351,6 +372,20 @@ grr_game_key_press_callback (GtkWidget *widget,
     }
 
     switch (event->keyval) {
+    case GDK_N:
+    case GDK_n:
+    case GDK_T:
+    case GDK_t:
+       grr_game_next (game);
+       break;
+    case GDK_P:
+    case GDK_p:
+       grr_game_pass (game);
+       break;
+    case GDK_Z:
+    case GDK_z:
+       grr_game_zap (game);
+       break;
     case GDK_B:
     case GDK_b:
        grr_board_view_set_active_robot (game->board_view, RR_ROBOT_BLUE);
@@ -382,20 +417,39 @@ grr_game_key_press_callback (GtkWidget *widget,
     case GDK_BackSpace:
        grr_board_view_undo (game->board_view);
        break;
+    case GDK_0:
+    case GDK_1:
+    case GDK_2:
+    case GDK_3:
+    case GDK_4:
+    case GDK_5:
+    case GDK_6:
+    case GDK_7:
+    case GDK_8:
+    case GDK_9:
+        {
+           int pos = -1;
+           const gchar *key = gdk_keyval_name (event->keyval);
+           gtk_widget_grab_focus (GTK_WIDGET (game->bid_entry));
+           gtk_editable_insert_text (GTK_EDITABLE (game->bid_entry),
+                                     key, strlen (key), &pos);
+           gtk_editable_set_position (GTK_EDITABLE (game->bid_entry), -1);
+       }
+       break;
     case GDK_space:
     case GDK_slash:
-       gtk_widget_grab_focus (GTK_WIDGET (game->command_entry));
+       gtk_widget_grab_focus (GTK_WIDGET (game->message_entry));
        if (event->keyval == GDK_slash) {
            int pos = -1;
-           gtk_editable_insert_text (GTK_EDITABLE (game->command_entry),
+           gtk_editable_insert_text (GTK_EDITABLE (game->message_entry),
                                      "/", 1, &pos);
-           gtk_editable_set_position (GTK_EDITABLE (game->command_entry), -1);
+           gtk_editable_set_position (GTK_EDITABLE (game->message_entry), -1);
        }
        break;
     case GDK_Q:
     case GDK_q:
        if (event->state & GDK_CONTROL_MASK) {
-           gtk_exit (0);
+           gtk_main_quit ();
        }
        break;
     }
@@ -403,18 +457,107 @@ grr_game_key_press_callback (GtkWidget *widget,
     return TRUE;
 }
 
+/* XXX: Messy, messy. I can't seem to make up my mind whether client
+   functions like such as these should be called here or in
+   grr_board_view. */
 static void
-grr_game_entry_callback (GtkWidget *widget,
-                        grr_game_t *game)
+grr_game_pass (grr_game_t *game)
+{
+    if (game->client == NULL)
+       return;
+
+    if (game->state == RR_GAMESTATE_SHOW)
+       rr_client_pass (game->client);
+    else
+       rr_client_revoke (game->client);
+}
+
+static void
+grr_game_zap (grr_game_t *game)
+{
+    if (game->client == NULL)
+       return;
+
+    rr_client_nobid (game->client);
+}
+
+static void
+grr_game_next (grr_game_t *game)
+{
+    if (game->client == NULL)
+       return;
+
+    if (game->state == RR_GAMESTATE_DONE)
+       rr_client_turn (game->client);
+    else
+       rr_client_abandon (game->client);
+}
+
+static void
+grr_game_pass_callback (GtkWidget *widget,
+                       grr_game_t *game)
+{
+    grr_game_pass (game);
+}
+
+static void
+grr_game_zap_callback (GtkWidget *widget,
+                       grr_game_t *game)
+{
+    grr_game_zap (game);
+}
+
+static void
+grr_game_next_callback (GtkWidget *widget,
+                       grr_game_t *game)
+{
+    grr_game_next (game);
+}
+
+static void
+grr_game_bid_entry_callback (GtkWidget *widget,
+                            grr_game_t *game)
+{
+    const gchar *bid_text;
+    char *end;
+    long bid;
+
+    if (game->client == NULL)
+       return;
+
+    bid_text = gtk_entry_get_text (GTK_ENTRY (game->bid_entry));
+
+    if (bid_text && bid_text[0]) {
+       bid = strtol (bid_text, &end, 10);
+       if (*end != '\0' && ! isspace (*end)) {
+           grr_game_printf (game, "\nInvalid bid value: %s", bid_text);
+       } else {
+           if (bid == 0)
+               rr_client_revoke (game->client);
+           else
+               rr_client_bid (game->client, bid);
+       }
+    }
+    
+    gtk_entry_set_text (GTK_ENTRY (game->bid_entry), "");
+    gtk_widget_grab_focus (GTK_WIDGET (game->message_view));
+}
+
+static void
+grr_game_message_entry_callback (GtkWidget *widget,
+                                grr_game_t *game)
 {
     rr_status_t status;
     const gchar *entry_text;
     char **response;
     int i;
 
-    entry_text = gtk_entry_get_text (GTK_ENTRY (game->command_entry));
+    if (game->client == NULL)
+       return;
+
+    entry_text = gtk_entry_get_text (GTK_ENTRY (game->message_entry));
 
-    if (entry_text && entry_text[0] && game->client) {
+    if (entry_text && entry_text[0]) {
        if (entry_text[0] == '/') {
            status = rr_client_request (game->client, entry_text + 1, &response);
            if (status) {
@@ -431,7 +574,7 @@ grr_game_entry_callback (GtkWidget *widget,
        }
     }
 
-    gtk_entry_set_text (GTK_ENTRY (game->command_entry), "");
+    gtk_entry_set_text (GTK_ENTRY (game->message_entry), "");
     gtk_widget_grab_focus (GTK_WIDGET (game->message_view));
 
 /* XXX: Huh? Why is this triggering valgrind?
@@ -495,15 +638,24 @@ grr_game_print (grr_game_t *game, const char *msg)
 }
 
 static int
-grr_game_start_gui (grr_game_t *game)
+grr_game_start_gui (grr_game_t *game, const char *user)
 {
     GtkWidget *board_frame;
     GtkWidget *vpaned;
     GtkWidget *sw;
     GtkWidget *vbox;
+    GtkWidget *hbox;
     GtkWidget *window;
     GtkWidget *message_view;
-    GtkWidget *command_entry;
+    GtkWidget *message_entry;
+    GtkWidget *bid_entry;
+    GtkWidget *bid_button;
+    GtkWidget *pass_button;
+    GtkWidget *zap_button;
+    GtkWidget *next_button;
+    GtkWidget *user_label;
+
+    game->state = RR_GAMESTATE_NEW;
 
     game->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
     window = game->window;
@@ -527,7 +679,6 @@ grr_game_start_gui (grr_game_t *game)
        gtk_text_buffer_create_mark (game->message_buffer,
                                     "end", &iter, FALSE);
        game->message_view = gtk_text_view_new_with_buffer (game->message_buffer);
-       game->command_entry = gtk_entry_new ();
 
        vpaned = gtk_vpaned_new ();
        gtk_container_set_border_width (GTK_CONTAINER (vpaned), 0);
@@ -558,13 +709,72 @@ grr_game_start_gui (grr_game_t *game)
        }
        gtk_widget_show (vpaned);
 
-       command_entry = game->command_entry;
-       gtk_box_pack_end (GTK_BOX (vbox), command_entry,
-                         FALSE, FALSE, 0);
-       gtk_widget_show (command_entry);
-       g_signal_connect (G_OBJECT (command_entry), "activate",
-                         G_CALLBACK (grr_game_entry_callback),
-                         (gpointer) game);
+       hbox = gtk_hbox_new (FALSE, 1);
+       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+       {
+           user_label = gtk_label_new (user);
+           gtk_box_pack_start (GTK_BOX (hbox), user_label,
+                               FALSE, FALSE, 1);
+           gtk_widget_show (user_label);
+
+           game->message_entry = gtk_entry_new ();
+           message_entry = game->message_entry;
+           gtk_box_pack_start (GTK_BOX (hbox), message_entry,
+                               TRUE, TRUE, 1);
+           gtk_widget_show (message_entry);
+           g_signal_connect (G_OBJECT (message_entry), "activate",
+                             G_CALLBACK (grr_game_message_entry_callback),
+                             (gpointer) game);
+       }
+       gtk_widget_show (hbox);
+           
+       hbox = gtk_hbox_new (FALSE, 1);
+       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+       {
+           bid_button = gtk_button_new_with_label ("Bid:");
+           gtk_box_pack_start (GTK_BOX (hbox), bid_button,
+                               FALSE, FALSE, 1);
+           gtk_widget_show (bid_button);
+           g_signal_connect (G_OBJECT (bid_button), "clicked",
+                             G_CALLBACK (grr_game_bid_entry_callback),
+                             (gpointer) game);
+
+           game->bid_entry = gtk_entry_new ();
+           bid_entry = game->bid_entry;
+           gtk_entry_set_max_length (GTK_ENTRY (bid_entry), 3);
+           gtk_entry_set_width_chars (GTK_ENTRY (bid_entry), 4);
+           gtk_box_pack_start (GTK_BOX (hbox), bid_entry,
+                               FALSE, FALSE, 0);
+           gtk_widget_show (bid_entry);
+           g_signal_connect (G_OBJECT (bid_entry), "activate",
+                             G_CALLBACK (grr_game_bid_entry_callback),
+                             (gpointer) game);
+
+           pass_button = gtk_button_new_with_label ("Pass");
+           gtk_box_pack_start (GTK_BOX (hbox), pass_button,
+                               FALSE, FALSE, 1);
+           gtk_widget_show (pass_button);
+           g_signal_connect (G_OBJECT (pass_button), "clicked",
+                             G_CALLBACK (grr_game_pass_callback),
+                             (gpointer) game);
+
+           zap_button = gtk_button_new_with_label ("Zap timer");
+           gtk_box_pack_start (GTK_BOX (hbox), zap_button,
+                               FALSE, FALSE, 1);
+           gtk_widget_show (zap_button);
+           g_signal_connect (G_OBJECT (zap_button), "clicked",
+                             G_CALLBACK (grr_game_zap_callback),
+                             (gpointer) game);
+
+           next_button = gtk_button_new_with_label ("Next turn");
+           gtk_box_pack_start (GTK_BOX (hbox), next_button,
+                               FALSE, FALSE, 1);
+           gtk_widget_show (next_button);
+           g_signal_connect (G_OBJECT (next_button), "clicked",
+                             G_CALLBACK (grr_game_next_callback),
+                             (gpointer) game);
+       }
+       gtk_widget_show (hbox);
     }
     gtk_widget_show (vbox);