From: Carl Worth Date: Sat, 12 Jul 2003 01:53:37 +0000 (+0000) Subject: Added keybindings/buttons for bid, pass, zap timer (nobid), and next turn X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=f1cf379f7a0932549fde7ca0a2b86d05fcd7af62;p=grrobot Added keybindings/buttons for bid, pass, zap timer (nobid), and next turn --- diff --git a/ChangeLog b/ChangeLog index fe01989..6100bf0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2003-07-11 Carl Worth + + * 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 * src/grrobot.c (grr_game_read_notices): Added support for diff --git a/src/grrobot.c b/src/grrobot.c index a56932d..a9a9d1e 100644 --- a/src/grrobot.c +++ b/src/grrobot.c @@ -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);