Got gameplay working and board resizing with window.
[gmemory:gmemory.git] / src / gmemory-card.c
1 /*
2  *  GMemory - gmemory-card.c
3  *
4  *  Copyright (C) 2010 Openismus GmbH
5  *
6  *  Author: Chris Kühl <chrisk@openismus.com>
7  *
8  *  This program is free software: you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation, either version 3 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "gmemory-card.h"
23 #include <glib/gprintf.h>
24
25 #define GMEMORY_CARD_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GMEMORY_TYPE_CARD, GMemoryCardPrivate))
26
27 enum {
28         PROP_0,
29
30         PROP_ID,
31         PROP_SIZE,
32         PROP_FACE_COLOR,
33         PROP_STATE
34 };
35
36
37 /* Define actions */
38 static ClutterColor card_colors[] = {
39         { 0xFF, 0x00, 0x00, 0xFF },
40         { 0x00, 0xFF, 0x00, 0xFF },
41         { 0x00, 0x00, 0xFF, 0xFF },
42         { 0x44, 0x3F, 0x00, 0xFF },
43         { 0x00, 0xFF, 0x6F, 0xFF },
44         { 0xFF, 0x00, 0xFF, 0xFF },
45         { 0x33, 0x12, 0x12, 0xFF },
46         { 0x57, 0x70, 0xA0, 0xFF },
47         { 0x1D, 0x22, 0x70, 0xFF },
48         { 0xFF, 0x6F, 0x90, 0xFF },
49         { 0xA0, 0x30, 0xDF, 0xFF },
50         { 0x33, 0x60, 0xFF, 0xFF },
51         { 0x77, 0x30, 0xAD, 0xFF },
52         { 0xBB, 0x00, 0xFF, 0xFF },
53         { 0xFF, 0x50, 0xF0, 0xFF },
54         { 0xFF, 0x00, 0x33, 0xFF },
55         { 0xBF, 0x04, 0x77, 0xFF },
56         { 0xFF, 0x00, 0xBB, 0xFF },
57         { 0xDF, 0xA0, 0x2F, 0xFF },
58         { 0x8F, 0xDF, 0x0F, 0xFF },
59         { 0x4F, 0x2F, 0x8F, 0xFF },
60         { 0x2F, 0x2F, 0x2F, 0xFF },
61         { 0xFF, 0x77, 0x00, 0xFF },
62         { 0x00, 0x77, 0xFF, 0xFF }
63 };
64
65 G_DEFINE_TYPE(GMemoryCard, gmemory_card, CLUTTER_TYPE_RECTANGLE);
66
67 struct _GMemoryCardPrivate {
68         guint            size; /* Cards are card_size-by-card_size squares. */
69         ClutterColor     face_color;
70         GMemoryCardState state;
71         guint            id; /* This is used to pair cards. */
72 };
73
74 static const ClutterColor default_face_color = {0xFF, 0xFF, 0xFF, 0xFF}; /* White */
75 static const ClutterColor default_back_color = {0x00, 0x00, 0x00, 0xFF}; /* Black */
76
77 static void
78 set_card_state(GMemoryCard *card, GMemoryCardState state) {
79         if (card->priv->state != state) {
80                 card->priv->state = state;
81                 g_object_notify(G_OBJECT(card), "state");
82         }
83 }
84
85 /* Property accessor functions. */
86 static void
87 gmemory_card_set_property(GObject      *object, guint       prop_id,
88                           const GValue *value,  GParamSpec *pspec) {
89         GMemoryCard *card = GMEMORY_CARD(object);
90
91         switch (prop_id) {
92         case PROP_ID:
93                 gmemory_card_set_id(card, g_value_get_uint(value));
94                 break;
95         case PROP_SIZE:
96                 gmemory_card_set_size(card, g_value_get_uint(value));
97                 break;
98         case PROP_FACE_COLOR:
99                 gmemory_card_set_face_color(card, g_value_get_string(value));
100                 break;
101         default:
102                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
103                 break;
104         }
105 }
106
107 static void
108 gmemory_card_get_property (GObject *object, guint       prop_id,
109                            GValue  *value,  GParamSpec *pspec) {
110         GMemoryCardPrivate *priv = GMEMORY_CARD(object)->priv;
111
112         switch (prop_id) {
113         case PROP_ID:
114                 g_value_set_uint(value, priv->id);
115                 break;
116         case PROP_SIZE:
117                 g_value_set_uint(value, priv->size);
118                 break;
119         case PROP_FACE_COLOR:
120                 g_value_set_string(value,
121                                    clutter_color_to_string(&(priv->face_color)));
122                 break;
123         case PROP_STATE:
124                 g_value_set_uint(value, priv->state);
125                 break;
126         default:
127                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
128                 break;
129         }
130 }
131
132 static void
133 gmemory_card_dispose(GObject *gobject) {
134         GMemoryCard *self = GMEMORY_CARD(gobject);
135
136         /* Chain up to the parent class */
137         G_OBJECT_CLASS(gmemory_card_parent_class)->dispose(gobject);
138 }
139
140 static void
141 gmemory_card_finalize(GObject *gobject) {
142         GMemoryCard *self = GMEMORY_CARD(gobject);
143
144         /* Chain up to the parent class */
145         G_OBJECT_CLASS(gmemory_card_parent_class)->finalize(gobject);
146 }
147
148 static void
149 gmemory_card_class_init(GMemoryCardClass *klass) {
150         GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
151         GParamSpec *pspec;
152
153         gobject_class->dispose      = gmemory_card_dispose;
154         gobject_class->finalize     = gmemory_card_finalize;
155
156         gobject_class->set_property = gmemory_card_set_property;
157         gobject_class->get_property = gmemory_card_get_property;
158
159         klass->card_back_color.red   = default_back_color.red;
160         klass->card_back_color.green = default_back_color.green;
161         klass->card_back_color.blue  = default_back_color.blue;
162         klass->card_back_color.alpha = default_back_color.alpha;
163
164         /* Properties. */
165         pspec = g_param_spec_uint("id", "ID",
166                                   "The card's id.",
167                                   0, 1000, 0,
168                                   G_PARAM_READABLE | G_PARAM_WRITABLE |
169                                   G_PARAM_STATIC_STRINGS);
170         g_object_class_install_property(gobject_class, PROP_ID, pspec);
171
172         pspec = g_param_spec_uint("size", "Size",
173                                   "Size of the square card's size.",
174                                   DEFAULT_CARD_SIZE,
175                                   DEFAULT_CARD_SIZE * 6,
176                                   DEFAULT_CARD_SIZE,
177                                   G_PARAM_READABLE | G_PARAM_WRITABLE |
178                                   G_PARAM_STATIC_STRINGS);
179         g_object_class_install_property(gobject_class, PROP_SIZE, pspec);
180
181         pspec = clutter_param_spec_color("face-color", "Face color",
182                                          "The cards face color",
183                                          &default_face_color,
184                                          G_PARAM_READABLE | G_PARAM_WRITABLE |
185                                          G_PARAM_STATIC_STRINGS);
186         g_object_class_install_property(gobject_class, PROP_FACE_COLOR, pspec);
187
188         pspec = g_param_spec_uint("state", "State",
189                                   "Weather the card is face down or up.",
190                                   CARD_STATE_FACE_DOWN,
191                                   CARD_STATE_FACE_UP,
192                                   CARD_STATE_FACE_DOWN,
193                                   G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
194         g_object_class_install_property(gobject_class, PROP_STATE, pspec);
195
196         g_type_class_add_private(klass, sizeof(GMemoryCardPrivate));
197 }
198
199 static void
200 gmemory_card_init(GMemoryCard *self) {
201         self->priv = GMEMORY_CARD_GET_PRIVATE(self);
202
203         self->priv->size = DEFAULT_CARD_SIZE; /* A square (h=w). */
204         clutter_actor_set_size(CLUTTER_ACTOR(self), self->priv->size,
205                                                     self->priv->size);
206
207         self->priv->face_color.red   = default_face_color.red; /* Default to white. */
208         self->priv->face_color.green = default_face_color.green;
209         self->priv->face_color.blue  = default_face_color.blue;
210         self->priv->face_color.alpha = default_face_color.alpha;
211         self->priv->state = CARD_STATE_FACE_DOWN;
212         self->priv->id = 0; /* 0 = Not paired. */
213
214         GMemoryCardClass * card_class = GMEMORY_CARD_GET_CLASS(self);
215         clutter_rectangle_set_color(CLUTTER_RECTANGLE(self),
216                                     &(card_class->card_back_color));
217
218 }
219
220 ClutterActor *
221 gmemory_card_new(guint id) {
222         return g_object_new(GMEMORY_TYPE_CARD, "id", id, NULL);
223 }
224
225 /* Getters. */
226 guint
227 gmemory_card_get_id(GMemoryCard *card) {
228         g_return_val_if_fail(GMEMORY_IS_CARD(card), 0);
229
230         return card->priv->id;
231 }
232
233 guint
234 gmemory_card_get_size(GMemoryCard *card) {
235         g_return_val_if_fail(GMEMORY_IS_CARD(card), 0);
236
237         return card->priv->size;
238 }
239
240 gchar *
241 gmemory_card_get_face_color(GMemoryCard *card) {
242         g_return_val_if_fail(GMEMORY_IS_CARD(card),
243                              clutter_color_to_string(&default_face_color));
244
245         return clutter_color_to_string(&(card->priv->face_color));
246 }
247
248 guint
249 gmemory_card_get_state(GMemoryCard *card) {
250         g_return_val_if_fail(GMEMORY_IS_CARD(card), 0);
251
252         return card->priv->state;
253 }
254
255 /* Setters */
256 void
257 gmemory_card_set_id(GMemoryCard *card, guint id) {
258         g_return_if_fail(GMEMORY_IS_CARD(card));
259
260         card->priv->id = id;
261 }
262
263 void
264 gmemory_card_set_size(GMemoryCard *card, guint size) {
265         g_return_if_fail(GMEMORY_IS_CARD(card));
266
267         card->priv->size = size;
268 }
269
270 void
271 gmemory_card_set_face_color(GMemoryCard *card, gchar * face_color) {
272         g_return_if_fail(GMEMORY_IS_CARD(card));
273
274         clutter_color_from_string(&(card->priv->face_color), face_color);
275 }
276
277 void gmemory_card_turn(GMemoryCard *card, gboolean turn_face_up) {
278         if(turn_face_up) {
279                 guint id = card->priv->id;
280                 clutter_rectangle_set_color(CLUTTER_RECTANGLE(card), &card_colors[id-1]);
281                 set_card_state(card, CARD_STATE_FACE_UP);
282                 clutter_actor_set_reactive(CLUTTER_ACTOR(card), FALSE);
283         } else {
284                 clutter_rectangle_set_color(CLUTTER_RECTANGLE(card),
285                                             &(GMEMORY_CARD_GET_CLASS(card)->card_back_color));
286                 set_card_state(card, CARD_STATE_FACE_DOWN);
287                 clutter_actor_set_reactive(CLUTTER_ACTOR(card), TRUE);
288         }
289 }