From: Carl Worth Date: Sat, 14 Jun 2003 08:17:41 +0000 (+0000) Subject: Added drag-and-drop (works but for handling queued notices). X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=568b9c54c55b5aa225060c9fdd4d777caf81043e;p=grrobot Added drag-and-drop (works but for handling queued notices). Fixed to peroperly grok, (and display results of) responses. --- diff --git a/src/Makefile.am b/src/Makefile.am index 8da7aeb..c37b50f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,7 +7,7 @@ grrobot_SOURCES = \ grr_board_view.c \ grr_board_view.h -INCLUDES = $(GRROBOT_CFLAGS) -Wall +INCLUDES = $(GRROBOT_CFLAGS) LDFLAGS = $(GRROBOT_LIBS) diff --git a/src/grr_board_view.c b/src/grr_board_view.c index 3092f4a..0903ff1 100644 --- a/src/grr_board_view.c +++ b/src/grr_board_view.c @@ -24,11 +24,15 @@ * Author: Carl Worth */ +#include +#include +#include +#include +#include + #include #include -#include -#include #include #include #include @@ -74,22 +78,29 @@ /* Forward declarations */ +static int +grr_sprintf_alloc (char **str, const char *fmt, ...); + +static int +grr_sprintf_alloc_va (char **str, const char *fmt, va_list ap); + + static void grr_board_view_class_init (grr_board_view_class_t *klass); static void grr_board_view_init (grr_board_view_t *view); static void grr_board_view_destroy (GtkObject *object); static void grr_board_view_realize (GtkWidget *widget); static void grr_board_view_size_request (GtkWidget *widget, - GtkRequisition *requisition); + GtkRequisition *requisition); static void grr_board_view_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); + GtkAllocation *allocation); static gint grr_board_view_expose (GtkWidget *widget, - GdkEventExpose *event); + GdkEventExpose *event); static gint grr_board_view_button_press (GtkWidget *widget, - GdkEventButton *event); + GdkEventButton *event); static gint grr_board_view_button_release (GtkWidget *widget, - GdkEventButton *event); + GdkEventButton *event); static gint grr_board_view_motion_notify (GtkWidget *widget, - GdkEventMotion *event); + GdkEventMotion *event); static void grr_board_view_update_mouse (grr_board_view_t *view, gint x, gint y); static void grr_board_view_update (grr_board_view_t *view); @@ -151,6 +162,7 @@ grr_board_view_init (grr_board_view_t *view) { view->board = NULL; view->owns_board = 0; + view->client = NULL; view->button = 0; view->timer = 0; @@ -195,17 +207,25 @@ grr_board_view_destroy (GtkObject *object) } void -grr_board_view_set_board (grr_board_view_t *view, +grr_board_view_set_board (grr_board_view_t *view, rr_board_t *board) { g_return_if_fail (view != NULL); - g_return_if_fail (GRR_IS_BOARD_VIEW (view)); view->board = board; grr_board_view_update (view); } +void +grr_board_view_set_client (grr_board_view_t *view, + rr_client_t *client) +{ + g_return_if_fail (view != NULL); + + view->client = client; +} + static void grr_board_view_realize (GtkWidget *widget) { @@ -581,72 +601,116 @@ grr_board_view_expose (GtkWidget *widget, return FALSE; } -/* static void grr_board_view_pointer_coords_to_grid (grr_board_view_t *view, int pointer_x, int pointer_y, - int *grid_x, af -*/ + int *grid_x, int *grid_y) +{ + *grid_x = (pointer_x - view->board_pad_x) / view->cell_width; + *grid_y = (pointer_y - view->board_pad_y) / view->cell_height; +} + + static gint grr_board_view_button_press (GtkWidget *widget, GdkEventButton *event) { - grr_board_view_t *view; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GRR_IS_BOARD_VIEW (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); + grr_board_view_t *view; + rr_cell_t cell; + int x, y; - view = GRR_BOARD_VIEW (widget); + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GRR_IS_BOARD_VIEW (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + view = GRR_BOARD_VIEW (widget); -/* - grr_board_view_pointer_coords_to_grid (view, event->x, event->y, &i, &j); -*/ + grr_board_view_pointer_coords_to_grid (view, + event->x, event->y, + &x, &y); -/* - if (!view->button && - rr_board_has_robot (view->board, i, j)) - { - gtk_grab_add (widget); + cell = rr_board_get_cell (view->board, x, y); + if (!view->button && RR_CELL_GET_ROBOT (cell)) { + + gtk_grab_add (widget); - view->button = event->button; + view->button = event->button; + view->drag_x = x; + view->drag_y = y; + view->drag_robot = RR_CELL_GET_ROBOT (cell); - grr_board_view_update_mouse (view, event->x, event->y); + grr_board_view_update_mouse (view, event->x, event->y); } - */ - return FALSE; + return FALSE; } static gint grr_board_view_button_release (GtkWidget *widget, GdkEventButton *event) { - grr_board_view_t *view; + grr_board_view_t *view; + const char *dir; + const char *robot; + int x, y; + int dx, dy; - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GRR_IS_BOARD_VIEW (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); + g_return_val_if_fail (widget != NULL, FALSE); + g_return_val_if_fail (GRR_IS_BOARD_VIEW (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); - view = GRR_BOARD_VIEW (widget); + view = GRR_BOARD_VIEW (widget); - if (view->button == event->button) { -/* + if (view->button == event->button) { gtk_grab_remove (widget); -*/ view->button = 0; -/* - grr_board_view_pointer_coords_to_grid (view, event->x, event->y, &i, &j); -*/ - - /* XXX: Need to compute direction based on (i, j) and old (i, j) */ -/* - rr_client_move (view->client, view->robot, direction); -*/ - - } + grr_board_view_pointer_coords_to_grid (view, event->x, event->y, &x, &y); + + dx = x - view->drag_x; + dy = y - view->drag_y; + if (dx == 0 && dy == 0) + return FALSE; + + if (abs(dx) > abs(dy)) + if (x > view->drag_x) + dir = "east"; + else + dir = "west"; + else + if (y > view->drag_y) + dir = "south"; + else + dir = "north"; + + switch (view->drag_robot) { + case RR_ROBOT_BLUE: + robot = "blue"; + break; + case RR_ROBOT_GREEN: + robot = "green"; + break; + case RR_ROBOT_RED: + robot = "RED"; + break; + case RR_ROBOT_YELLOW: + robot = "YELLOW"; + break; + default: + return FALSE; + } + + if (view->client) { + char *move_str; + + grr_sprintf_alloc (&move_str, "%s %s", robot, dir); + if (move_str == NULL) + return FALSE; + rr_client_move (view->client, move_str); + free (move_str); + } + } return FALSE; } @@ -697,13 +761,10 @@ grr_board_view_motion_notify (GtkWidget *widget, static void grr_board_view_update_mouse (grr_board_view_t *view, gint x, gint y) { - gint xc, yc; - g_return_if_fail (view != NULL); g_return_if_fail (GRR_IS_BOARD_VIEW (view)); - xc = GTK_WIDGET(view)->allocation.width / 2; - yc = GTK_WIDGET(view)->allocation.height / 2; + /* XXX: Should draw a robot here */ } static void @@ -714,3 +775,47 @@ grr_board_view_update (grr_board_view_t *view) gtk_widget_queue_draw (GTK_WIDGET (view)); } + +static int +grr_sprintf_alloc (char **str, const char *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = grr_sprintf_alloc_va (str, fmt, ap); + va_end(ap); + + return ret; +} + +/* ripped more or less straight out of PRINTF(3) */ +static int +grr_sprintf_alloc_va (char **str, const char *fmt, va_list ap) +{ + char *new_str; + /* Guess we need no more than 100 bytes. */ + int n, size = 100; + + if ((*str = malloc (size)) == NULL) + return -1; + while (1) { + /* Try to print in the allocated space. */ + n = vsnprintf (*str, size, fmt, ap); + /* If that worked, return the size. */ + if (n > -1 && n < size) + return n; + /* Else try again with more space. */ + if (n > -1) /* glibc 2.1 */ + size = n+1; /* precisely what is needed */ + else /* glibc 2.0 */ + size *= 2; /* twice the old size */ + new_str = realloc(*str, size); + if (new_str == NULL) { + free(*str); + *str = NULL; + return -1; + } + *str = new_str; + } +} diff --git a/src/grr_board_view.h b/src/grr_board_view.h index 87aeebc..d8ded6e 100644 --- a/src/grr_board_view.h +++ b/src/grr_board_view.h @@ -56,7 +56,10 @@ struct grr_board_view int cell_width, cell_height; - /* XXX: Obviously, the rest of this needs to be gutted */ + int drag_x, drag_y; + rr_robot_t drag_robot; + + rr_client_t *client; /* Button currently pressed or 0 if none */ guint8 button; @@ -70,10 +73,20 @@ struct grr_board_view_class GtkWidgetClass parent_class; }; -GtkWidget* grr_board_view_new (rr_board_t *board); -GtkType grr_board_view_get_type (void); -void grr_board_view_set_board (grr_board_view_t *view, - rr_board_t *board); +GtkWidget* +grr_board_view_new (rr_board_t *board); + +GtkType +grr_board_view_get_type (void); + +void +grr_board_view_set_board (grr_board_view_t *view, + rr_board_t *board); + +void +grr_board_view_set_client (grr_board_view_t *view, + rr_client_t *client); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/src/grrobot.c b/src/grrobot.c index 332cca5..0154c0e 100644 --- a/src/grrobot.c +++ b/src/grrobot.c @@ -176,17 +176,33 @@ grr_game_read_notices (grr_game_t *game) } static void -command_callback (GtkWidget *widget, - grr_game_t *game) +grr_game_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)); - gtk_text_buffer_insert_at_cursor (game->message_buffer, entry_text, -1); - gtk_text_buffer_insert_at_cursor (game->message_buffer, "\n", -1); - rr_client_request (game->client, entry_text, &response); + status = rr_client_request (game->client, entry_text, &response); + if (status) { + gtk_text_buffer_insert_at_cursor (game->message_buffer, + "ERROR: ", -1); + gtk_text_buffer_insert_at_cursor (game->message_buffer, + rr_status_str (status), -1); + gtk_text_buffer_insert_at_cursor (game->message_buffer, + "\n", -1); + } else { + for (i=0; response[i]; i++) { + gtk_text_buffer_insert_at_cursor (game->message_buffer, + response[i], -1); + gtk_text_buffer_insert_at_cursor (game->message_buffer, + " ", -1); + } + gtk_text_buffer_insert_at_cursor (game->message_buffer, "\n", -1); + } gtk_entry_set_text (GTK_ENTRY (game->command_entry), ""); @@ -227,6 +243,8 @@ grr_game_start_gui (grr_game_t *game) gtk_paned_pack1 (GTK_PANED (vpaned), board_frame, TRUE, TRUE); { game->board_view = grr_board_view_new (game->board); + grr_board_view_set_client (GRR_BOARD_VIEW (game->board_view), + game->client); gtk_container_add (GTK_CONTAINER (board_frame), game->board_view); gtk_widget_show (game->board_view); @@ -256,7 +274,7 @@ grr_game_start_gui (grr_game_t *game) gtk_container_add (GTK_CONTAINER (vbox), command_entry); gtk_widget_show (command_entry); g_signal_connect (G_OBJECT (command_entry), "activate", - G_CALLBACK (command_callback), + G_CALLBACK (grr_game_entry_callback), (gpointer) game); } gtk_widget_show (vbox);