2 * Copyright (C) 2008 Carl Worth
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see http://www.gnu.org/licenses/ .
17 * Author: Carl Worth <cworth@cworth.org>
23 #include "loa-board.h"
38 loa_bool_t has_selected;
44 on_delete_event_quit (GtkWidget *widget,
50 /* Returning FALSE allows the default handler for delete-event
51 * to proceed to cleanup the widget. */
55 /* Something like buff */
56 #define LIGHT_SQUARE_COLOR 0.89, 0.70, 0.40
57 /* Something like mahogany */
58 #define DARK_SQUARE_COLOR 0.26, 0.02, 0.01
61 on_button_press_event (GtkWidget *widget,
62 GdkEventButton *event,
65 loa_game_t *game = user_data;
66 layout_t *layout = &game->layout;
70 x = (event->x - layout->x_offset) / layout->cell_size;
71 y = (event->y - layout->y_offset) / layout->cell_size;
73 if (! game->has_selected) {
74 if (game->board.cells[x][y] == game->board.player) {
75 game->has_selected = TRUE;
78 gtk_widget_queue_draw (widget);
83 /* Do nothing for out-of-bounds clicks */
84 if (x < 0 || x >= LOA_BOARD_SIZE ||
85 y < 0 || y >= LOA_BOARD_SIZE)
90 if (x == game->selected_x &&
91 y == game->selected_y)
93 game->has_selected = FALSE;
94 gtk_widget_queue_draw (widget);
98 if (loa_board_move (&game->board,
99 game->selected_x, game->selected_y,
102 game->has_selected = FALSE;
103 gtk_widget_queue_draw (widget);
106 printf ("Illegal move %c%d%c%d: %s\n",
107 'a' + game->selected_x,
108 LOA_BOARD_SIZE - game->selected_y,
118 on_expose_event_draw (GtkWidget *widget,
119 GdkEventExpose *event,
122 loa_game_t *game = user_data;
123 layout_t *layout = &game->layout;
127 if (layout->width != widget->allocation.width ||
128 layout->height != widget->allocation.height)
132 layout->width = widget->allocation.width;
133 layout->height = widget->allocation.height;
135 size = MIN (layout->width, layout->height);
136 /* Size must be a multiple of the integer cell_size */
137 layout->cell_size = size / BOARD_SIZE;
138 size = layout->cell_size * BOARD_SIZE;
140 layout->x_offset = (layout->width - size) / 2;
141 layout->y_offset = (layout->height - size) / 2;
144 cr = gdk_cairo_create (widget->window);
146 cairo_translate (cr, layout->x_offset, layout->y_offset);
148 for (y = 0; y < BOARD_SIZE; y++) {
149 for (x = 0; x < BOARD_SIZE; x++) {
152 cairo_translate(cr, x * layout->cell_size, y * layout->cell_size);
153 if ((x + y) % 2 == 0)
154 cairo_set_source_rgb (cr, LIGHT_SQUARE_COLOR);
156 cairo_set_source_rgb (cr, DARK_SQUARE_COLOR);
157 cairo_rectangle (cr, 0, 0, layout->cell_size, layout->cell_size);
159 cell = game->board.cells[x][y];
160 if (cell != LOA_CELL_EMPTY) {
162 layout->cell_size / 2.0, layout->cell_size / 2.0,
163 layout->cell_size / 2.5,
165 if (cell == LOA_CELL_BLACK)
166 cairo_set_source_rgb (cr, 0, 0, 0); /* black */
168 cairo_set_source_rgb (cr, 1, 1, 1); /* white */
169 cairo_fill_preserve (cr);
170 cairo_set_line_width (cr, 2.0);
171 if (cell == LOA_CELL_BLACK)
172 cairo_set_source_rgb (cr, LIGHT_SQUARE_COLOR);
174 cairo_set_source_rgb (cr, DARK_SQUARE_COLOR);
177 if (game->has_selected &&
178 x == game->selected_x &&
179 y == game->selected_y)
182 layout->cell_size / 2.0, layout->cell_size / 2.0,
183 layout->cell_size / 2.5,
185 cairo_set_source_rgba (cr, 0.2, 0.2, 1.0, 0.4);
198 loa_game_init (loa_game_t *game)
200 game->layout.width = 0;
201 game->layout.height = 0;
203 game->has_selected = FALSE;
205 loa_board_init (&game->board);
209 main (int argc, char *argv[])
212 GtkWidget *drawing_area;
215 loa_game_init (&game);
217 gtk_init (&argc, &argv);
219 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
221 gtk_window_set_default_size (GTK_WINDOW (window), 256, 256);
223 g_signal_connect (window, "delete-event",
224 G_CALLBACK (on_delete_event_quit), NULL);
226 drawing_area = gtk_drawing_area_new ();
228 gtk_container_add (GTK_CONTAINER (window), drawing_area);
230 g_signal_connect (drawing_area, "expose-event",
231 G_CALLBACK (on_expose_event_draw), &game);
233 gtk_widget_add_events (drawing_area, GDK_BUTTON_PRESS_MASK);
234 g_signal_connect (drawing_area, "button-press-event",
235 G_CALLBACK (on_button_press_event), &game);
237 gtk_widget_show_all (window);