]> git.cworth.org Git - loa/blob - loa.c
3333fc33eb75a56ddb1a99285f5cb7736f9bc97f
[loa] / loa.c
1 /*
2  * Copyright (C) 2008 Carl Worth
3  *
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.
8  *
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.
13  *
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/ .
16  *
17  * Author: Carl Worth <cworth@cworth.org>
18  */
19
20 #include <gtk/gtk.h>
21 #include <math.h>
22
23 #include "loa-board.h"
24
25 #define BOARD_SIZE 8
26
27 typedef struct {
28     int x_offset;
29     int y_offset;
30     int width;
31     int height;
32     int cell_size;
33 } layout_t;
34
35 typedef struct {
36     layout_t layout;
37     loa_board_t board;
38 } loa_game_t;
39
40 static gboolean
41 on_delete_event_quit (GtkWidget  *widget,
42                       GdkEvent   *event,
43                       gpointer    user_data)
44 {
45     gtk_main_quit ();
46
47     /* Returning FALSE allows the default handler for delete-event
48      * to proceed to cleanup the widget. */
49     return FALSE;
50 }
51
52 /* Something like buff */
53 #define LIGHT_SQUARE_COLOR 0.89, 0.70, 0.40
54 /* Something like mahogany */
55 #define DARK_SQUARE_COLOR  0.26, 0.02, 0.01
56
57 static gboolean
58 on_expose_event_draw (GtkWidget         *widget,
59                       GdkEventExpose    *event,
60                       gpointer           user_data)
61 {
62     loa_game_t *game = user_data;
63     layout_t *layout = &game->layout;
64     cairo_t *cr;
65     int x, y;
66
67     if (layout->width != widget->allocation.width ||
68         layout->height != widget->allocation.height)
69     {
70         int size;
71
72         layout->width = widget->allocation.width;
73         layout->height = widget->allocation.height;
74
75         size = MIN (layout->width, layout->height);
76         /* Size must be a multiple of the integer cell_size */
77         layout->cell_size = size / BOARD_SIZE;
78         size = layout->cell_size * BOARD_SIZE;
79
80         layout->x_offset = (layout->width - size) / 2;
81         layout->y_offset = (layout->height - size) / 2;
82     }
83
84     cr = gdk_cairo_create (widget->window);
85
86     cairo_translate (cr, layout->x_offset, layout->y_offset);
87
88     for (y = 0; y < BOARD_SIZE; y++) {
89         for (x = 0; x < BOARD_SIZE; x++) {
90             loa_cell_t cell;
91             cairo_save (cr);
92             cairo_translate(cr, x * layout->cell_size, y * layout->cell_size);
93             if ((x + y) % 2 == 0)
94                 cairo_set_source_rgb (cr, LIGHT_SQUARE_COLOR);
95             else
96                 cairo_set_source_rgb (cr, DARK_SQUARE_COLOR);
97             cairo_rectangle (cr, 0, 0, layout->cell_size, layout->cell_size);
98             cairo_fill (cr);
99             cell = game->board.cells[x][y];
100             if (cell != LOA_CELL_EMPTY) {
101                 cairo_arc (cr,
102                            layout->cell_size / 2.0, layout->cell_size / 2.0,
103                            layout->cell_size / 2.5,
104                            0, 2 * M_PI);
105                 if (cell == LOA_CELL_BLACK)
106                     cairo_set_source_rgb (cr, 0, 0, 0); /* black */
107                 else
108                     cairo_set_source_rgb (cr, 1, 1, 1); /* white */
109                 cairo_fill_preserve (cr);
110                 cairo_set_line_width (cr, 2.0);
111                 if (cell == LOA_CELL_BLACK)
112                     cairo_set_source_rgb (cr, LIGHT_SQUARE_COLOR);
113                 else
114                     cairo_set_source_rgb (cr, DARK_SQUARE_COLOR);
115                 cairo_stroke (cr);
116             }
117             cairo_restore (cr);
118         }
119     }
120
121     cairo_destroy (cr);
122
123     return TRUE;
124 }
125
126 static void
127 loa_game_init (loa_game_t *game)
128 {
129     game->layout.width = 0;
130     game->layout.height = 0;
131
132     loa_board_init (&game->board);
133 }
134
135 int
136 main (int argc, char *argv[])
137 {
138     GtkWidget *window;
139     GtkWidget *drawing_area;
140     loa_game_t game;
141
142     loa_game_init (&game);
143
144     gtk_init (&argc, &argv);
145
146     window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
147
148     gtk_window_set_default_size (GTK_WINDOW (window), 256, 256);
149
150     g_signal_connect (window, "delete-event",
151                       G_CALLBACK (on_delete_event_quit), NULL);
152
153     drawing_area = gtk_drawing_area_new ();
154
155     gtk_container_add (GTK_CONTAINER (window), drawing_area);
156
157     g_signal_connect (drawing_area, "expose-event",  
158                       G_CALLBACK (on_expose_event_draw), &game);
159
160     gtk_widget_show_all (window);
161     
162     gtk_main ();
163
164     return 0;
165 }