711df113b0d1a4bf259242d1d1dd55477f2ff7b1
[ruby-edje.git] / src / rb_edje.c
1 /*
2  * $Id: rb_edje.c 129 2004-10-22 17:03:35Z tilman $
3  *
4  * Copyright (C) 2004 Tilman Sauerbeck (tilman at code-monkey de)
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <ruby.h>
22
23 #include <Edje.h>
24 #include <evas/rb_evas.h>
25 #include <evas/rb_evas_object.h>
26
27 #define __RB_EDJE_C
28 #include "rb_edje.h"
29 #include "rb_edje_main.h"
30 #include "rb_part.h"
31
32 VALUE cEdje;
33
34 static void c_mark (RbEdje *e)
35 {
36         c_evas_object_mark (&e->real);
37
38         rb_gc_mark (e->parts);
39         rb_gc_mark (e->callbacks);
40
41         if (!NIL_P (e->on_text_changed_cb))
42                 rb_gc_mark (e->on_text_changed_cb);
43 }
44
45 static void c_free (RbEdje *e)
46 {
47         c_evas_object_free (&e->real, false);
48
49         edje_shutdown ();
50 }
51
52 /*
53  * call-seq:
54  *  Edje::Edje.new(evas) => edje
55  *
56  * Creates an Edje::Edje object.
57  */
58 static VALUE c_new (VALUE klass, VALUE evas)
59 {
60         VALUE self, argv[1];
61         RbEdje *edje = NULL;
62
63         CHECK_CLASS (evas, cEvas);
64         GET_OBJ (evas, RbEvas, e);
65
66         edje_init ();
67
68         self = Data_Make_Struct (klass, RbEdje, c_mark, c_free, edje);
69
70         edje->real.real = edje_object_add (e->real);
71         edje->parts = rb_hash_new ();
72         edje->callbacks = rb_ary_new ();
73         edje->on_text_changed_cb = Qnil;
74
75         argv[0] = evas;
76         rb_obj_call_init (self, 1, argv);
77
78         return self;
79 }
80
81 /*
82  * call-seq:
83  *  edje.freeze => nil
84  *
85  * Freezes <i>edje</i>.
86  */
87 static VALUE c_freeze (VALUE self)
88 {
89         GET_OBJ (self, RbEdje, e);
90
91         edje_object_freeze (e->real.real);
92
93         return Qnil;
94 }
95
96 /*
97  * call-seq:
98  *  edje.thaw => nil
99  *
100  * Thaws <i>edje</i>.
101  */
102 static VALUE c_thaw (VALUE self)
103 {
104         GET_OBJ (self, RbEdje, e);
105
106         edje_object_thaw (e->real.real);
107
108         return Qnil;
109 }
110
111 /*
112  * call-seq:
113  *  edje.load(eet, group) => nil
114  *
115  * Loads <i>eet</i> into <i>edje</i>. <i>group</i> is the
116  * name of the group to be displayed.
117  */
118 static VALUE c_load (VALUE self, VALUE eet, VALUE group)
119 {
120         GET_OBJ (self, RbEdje, e);
121
122         Check_Type (eet, T_STRING);
123         Check_Type (group, T_STRING);
124
125         if (!edje_object_file_set (e->real.real, StringValuePtr (eet),
126                                    StringValuePtr (group)))
127                 rb_raise (rb_eException, "Cannot load eet");
128
129         return Qnil;
130 }
131
132 /*
133  * call-seq:
134  *  edje.get_size_min => array
135  *
136  * Returns an array that contains the minimum size
137  * of <i>edje</i>.
138  */
139 static VALUE c_get_size_min (VALUE self)
140 {
141         int w = 0, h = 0;
142
143         GET_OBJ (self, RbEdje, e);
144
145         edje_object_size_min_get (e->real.real, &w, &h);
146
147         return rb_ary_new3 (2, INT2FIX (w), INT2FIX (h));
148 }
149
150 /*
151  * call-seq:
152  *  edje.get_size_max => array
153  *
154  * Returns an array that contains the maximum size
155  * of <i>edje</i>.
156  */
157 static VALUE c_get_size_max (VALUE self)
158 {
159         int w = 0, h = 0;
160
161         GET_OBJ (self, RbEdje, e);
162
163         edje_object_size_max_get (e->real.real, &w, &h);
164
165         return rb_ary_new3 (2, INT2FIX (w), INT2FIX (h));
166 }
167
168 /*
169  * call-seq:
170  *  edje.part_exists?(part) => true or false
171  *
172  * Returns true if <i>edje</i> has a part called <i>part</i>,
173  * else returns false.
174  */
175 static VALUE c_part_exists_get (VALUE self, VALUE name)
176 {
177         int r;
178
179         GET_OBJ (self, RbEdje, e);
180
181         Check_Type (name, T_STRING);
182
183         r = edje_object_part_exists (e->real.real, StringValuePtr (name));
184
185         return r ? Qtrue : Qfalse;
186 }
187
188 /*
189  * call-seq:
190  *  edje.part(part_name) => part
191  *
192  * Returns the <code>Edje::Part</code> object that corresponds to
193  * <i>part_name</i>. If there's no part with that name in <i>edje</i>,
194  * an exception is raised.
195  */
196 static VALUE c_part_get (VALUE self, VALUE name)
197 {
198         VALUE part;
199
200         GET_OBJ (self, RbEdje, e);
201         Check_Type (name, T_STRING);
202
203         if (!edje_object_part_exists (e->real.real, StringValuePtr (name))) {
204                 rb_raise (rb_eException, "Unknown part name");
205                 return Qnil;
206         }
207
208         if (NIL_P (part = rb_hash_aref (e->parts, name))) {
209                 part = TO_PART (self, name);
210                 rb_hash_aset (e->parts, name, part);
211         }
212
213         return part;
214 }
215
216 static void on_text_changed (void *data, Evas_Object *eo,
217                              const char *part_name)
218 {
219         VALUE self = (VALUE) data, part, name;
220
221         GET_OBJ (self, RbEdje, e);
222
223         name = rb_str_new2 (part_name);
224
225         if (NIL_P (part = rb_hash_aref (e->parts, name))) {
226                 part = TO_PART (self, name);
227                 rb_hash_aset (e->parts, name, part);
228         }
229
230         rb_funcall (e->on_text_changed_cb,
231                     rb_intern ("call"), 1, part);
232 }
233
234 /*
235  * call-seq:
236  *  edje.on_text_changed { |part_obj| block }
237  *
238  * Registers a callback that will get called when the text
239  * of any part is changed in <i>edje</i>.
240  * The block is passed the <code>Edje::Part</code> object
241  * of which the text changed.
242  */
243 static VALUE c_on_text_changed (VALUE self)
244 {
245         GET_OBJ (self, RbEdje, e);
246
247         if (!rb_block_given_p ())
248                 return Qnil;
249
250         e->on_text_changed_cb = rb_block_proc ();
251
252         edje_object_text_change_cb_set (e->real.real, on_text_changed,
253                                         (void *) self);
254
255         return Qnil;
256 }
257
258 /*
259  * call-seq:
260  *  edje.emit_signal(signal, source) => nil
261  *
262  * Emits a signal to <i>edje</i>.
263  *
264  *  edje.emit_signal("signal_foo", "part_bar") #=> nil
265  */
266 static VALUE c_emit_signal (VALUE self, VALUE signal, VALUE source)
267 {
268         GET_OBJ (self, RbEdje, e);
269
270         Check_Type (signal, T_STRING);
271         Check_Type (source, T_STRING);
272
273         edje_object_signal_emit (e->real.real, StringValuePtr (signal),
274                                  StringValuePtr (source));
275
276         return Qnil;
277 }
278
279 static void on_signal (void *data, Evas_Object *o,
280                        const char *signal, const char *src)
281 {
282         rb_funcall ((VALUE) data, rb_intern ("call"), 2,
283                     rb_str_new2 (signal), rb_str_new2 (src));
284 }
285
286 /*
287  * call-seq:
288  *  edje.on_signal(signal [, source]) { |signal, source| block } => nil
289  *
290  * Registers a callback that will get called when <i>signal</i>
291  * is emitted by <i>source</i>.
292  * If source is nil, "*" will be used instead.
293  * The block is passed two strings, signal and source, which identify
294  * the emission.
295  */
296 static VALUE c_on_signal (int argc, VALUE *argv, VALUE self)
297 {
298         VALUE signal, src, cb;
299         char *ssrc = "*";
300
301         GET_OBJ (self, RbEdje, e);
302
303         rb_scan_args (argc, argv, "11", &signal, &src);
304
305         Check_Type (signal, T_STRING);
306
307         if (!NIL_P (src)) {
308                 Check_Type (src, T_STRING);
309                 ssrc = StringValuePtr (src);
310         }
311
312         if (!rb_block_given_p ())
313                 return Qnil;
314
315         cb = rb_block_proc ();
316         rb_ary_push (e->callbacks, cb);
317
318         edje_object_signal_callback_add (e->real.real,
319                                          StringValuePtr (signal),
320                                          ssrc, on_signal, (void *) cb);
321
322         return Qnil;
323 }
324
325 /*
326  * call-seq:
327  *  edje.play? => true or false
328  *
329  * Returns true if <i>edje</i> is in play mode, else returns false.
330  */
331 static VALUE c_play_get (VALUE self)
332 {
333         GET_OBJ (self, RbEdje, e);
334
335         return edje_object_play_get (e->real.real) ? Qtrue : Qfalse;
336 }
337
338 /*
339  * call-seq:
340  *  edje.play(true or false)
341  *
342  * Sets <i>edje</i> to play resp. pause mode.
343  */
344 static VALUE c_play_set (VALUE self, VALUE val)
345 {
346         GET_OBJ (self, RbEdje, e);
347
348         CHECK_BOOL(val);
349
350         edje_object_play_set (e->real.real, val == Qtrue);
351
352         return Qnil;
353 }
354
355 /*
356  * call-seq:
357  *  edje.animation? => true or false
358  *
359  * Returns the animation state of <i>edje</i>.
360  */
361 static VALUE c_animation_get (VALUE self)
362 {
363         GET_OBJ (self, RbEdje, e);
364
365         return edje_object_animation_get (e->real.real) ? Qtrue : Qfalse;
366 }
367
368 /*
369  * call-seq:
370  *  edje.animation(true or false)
371  *
372  * Sets the animation state of <i>edje</i>.
373  */
374 static VALUE c_animation_set (VALUE self, VALUE val)
375 {
376         GET_OBJ (self, RbEdje, e);
377
378         CHECK_BOOL(val);
379
380         edje_object_animation_set (e->real.real, val == Qtrue);
381
382         return Qnil;
383 }
384
385 static VALUE c_data_get (VALUE self, VALUE key)
386 {
387         const char *s;
388
389         GET_OBJ (self, RbEdje, e);
390
391         Check_Type (key, T_STRING);
392
393         s = edje_object_data_get (e->real.real, StringValuePtr (key));
394
395         return s ? rb_str_new2 (s) : Qnil;
396 }
397
398 void Init_Edje (void)
399 {
400         cEdje = rb_define_class_under (mEdje, "Edje", cEvasObject);
401
402         rb_define_singleton_method (cEdje, "new", c_new, 1);
403         rb_define_method (cEdje, "freeze", c_freeze, 0);
404         rb_define_method (cEdje, "thaw", c_thaw, 0);
405         rb_define_method (cEdje, "load", c_load, 2);
406         rb_define_method (cEdje, "get_size_min", c_get_size_min, 0);
407         rb_define_method (cEdje, "get_size_max", c_get_size_max, 0);
408         rb_define_method (cEdje, "part_exists?", c_part_exists_get, 1);
409         rb_define_method (cEdje, "part", c_part_get, 1);
410         rb_define_method (cEdje, "on_text_changed", c_on_text_changed, 0);
411         rb_define_method (cEdje, "emit_signal", c_emit_signal, 2);
412         rb_define_method (cEdje, "on_signal", c_on_signal, -1);
413         rb_define_method (cEdje, "play?", c_play_get, 0);
414         rb_define_method (cEdje, "play=", c_play_set, 1);
415         rb_define_method (cEdje, "animation?", c_animation_get, 0);
416         rb_define_method (cEdje, "animation=", c_animation_set, 1);
417         rb_define_method (cEdje, "data", c_data_get, 1);
418 }