Documentation arrived.
[ruby-edje.git] / src / rb_edje.c
1 /*
2  * $Id: rb_edje.c 59 2004-08-10 14:10:31Z 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>, else false.
173  */
174 static VALUE c_part_exists_get (VALUE self, VALUE name)
175 {
176         int r;
177
178         GET_OBJ (self, RbEdje, e);
179
180         Check_Type (name, T_STRING);
181
182         r = edje_object_part_exists (e->real.real, StringValuePtr (name));
183
184         return r ? Qtrue : Qfalse;
185 }
186
187 /*
188  * call-seq:
189  *  edje.part(part_name) => part
190  *
191  * Returns the <code>Edje::Part</code> object that corresponds to
192  * <i>part_name</i>. If there's no part with that name in <i>edje</i>,
193  * an exception is raised.
194  */
195 static VALUE c_part_get (VALUE self, VALUE name)
196 {
197         VALUE part;
198
199         GET_OBJ (self, RbEdje, e);
200         Check_Type (name, T_STRING);
201
202         if (!edje_object_part_exists (e->real.real, StringValuePtr (name))) {
203                 rb_raise (rb_eException, "Unknown part name");
204                 return Qnil;
205         }
206
207         if (NIL_P (part = rb_hash_aref (e->parts, name))) {
208                 part = TO_PART (self, name);
209                 rb_hash_aset (e->parts, name, part);
210         }
211
212         return part;
213 }
214
215 static void on_text_changed (void *data, Evas_Object *eo,
216                              const char *part_name)
217 {
218         VALUE self = (VALUE) data, part, name;
219
220         GET_OBJ (self, RbEdje, e);
221
222         name = rb_str_new2 (part_name);
223
224         if (NIL_P (part = rb_hash_aref (e->parts, name))) {
225                 part = TO_PART (self, name);
226                 rb_hash_aset (e->parts, name, part);
227         }
228
229         rb_funcall (e->on_text_changed_cb,
230                     rb_intern ("call"), 1, part);
231 }
232
233 /*
234  * call-seq:
235  *  edje.on_text_changed { |part_obj| block }
236  *
237  * Registers a callback that will get called when the text
238  * of any part is changed in <i>edje</i>.
239  * The block is passed the <code>Edje::Part</code> object
240  * of which the text changed.
241  */
242 static VALUE c_on_text_changed (VALUE self)
243 {
244         GET_OBJ (self, RbEdje, e);
245
246         if (!rb_block_given_p ())
247                 return Qnil;
248
249         e->on_text_changed_cb = rb_block_proc ();
250
251         edje_object_text_change_cb_set (e->real.real, on_text_changed,
252                                         (void *) self);
253
254         return Qnil;
255 }
256
257 /*
258  * call-seq:
259  *  edje.emit_signal(signal, source) => nil
260  *
261  * Emits a signal to <i>edje</i>.
262  *
263  *  edje.emit_signal("signal_foo", "part_bar") #=> nil
264  */
265 static VALUE c_emit_signal (VALUE self, VALUE signal, VALUE source)
266 {
267         GET_OBJ (self, RbEdje, e);
268
269         Check_Type (signal, T_STRING);
270         Check_Type (source, T_STRING);
271
272         edje_object_signal_emit (e->real.real, StringValuePtr (signal),
273                                  StringValuePtr (source));
274
275         return Qnil;
276 }
277
278 static void on_signal (void *data, Evas_Object *o,
279                        const char *signal, const char *src)
280 {
281         rb_funcall ((VALUE) data, rb_intern ("call"), 2,
282                     rb_str_new2 (signal), rb_str_new2 (src));
283 }
284
285 /*
286  * call-seq:
287  *  edje.on_signal(signal, source) { |signal, source| block } => nil
288  *
289  * Registers a callback that will get called when <i>signal</i>
290  * is emitted by <i>source</i>.
291  * The block is passed two strings, signal and source, which identify
292  * the emission.
293  */
294 static VALUE c_on_signal (VALUE self, VALUE signal, VALUE src)
295 {
296         VALUE cb;
297
298         GET_OBJ (self, RbEdje, e);
299
300         Check_Type (signal, T_STRING);
301         Check_Type (src, T_STRING);
302
303         if (!rb_block_given_p ())
304                 return Qnil;
305
306         cb = rb_block_proc ();
307         rb_ary_push (e->callbacks, cb);
308
309         edje_object_signal_callback_add (e->real.real,
310                                          StringValuePtr (signal),
311                                          StringValuePtr (src), on_signal,
312                                          (void *) cb);
313
314         return Qnil;
315 }
316
317 /*
318  * call-seq:
319  *  edje.play? => true or false
320  *
321  * Returns true if <i>edje</i> is in play mode, else false.
322  */
323 static VALUE c_play_get (VALUE self)
324 {
325         GET_OBJ (self, RbEdje, e);
326
327         return edje_object_play_get (e->real.real) ? Qtrue : Qfalse;
328 }
329
330 /*
331  * call-seq:
332  *  edje.play(true or false)
333  *
334  * Sets <i>edje</i> to play resp. pause mode.
335  */
336 static VALUE c_play_set (VALUE self, VALUE val)
337 {
338         GET_OBJ (self, RbEdje, e);
339
340         CHECK_BOOL(val);
341
342         edje_object_play_set (e->real.real, val == Qtrue);
343
344         return Qnil;
345 }
346
347 /*
348  * call-seq:
349  *  edje.animation? => true or false
350  *
351  * Returns the animation state of <i>edje</i>.
352  */
353 static VALUE c_animation_get (VALUE self)
354 {
355         GET_OBJ (self, RbEdje, e);
356
357         return edje_object_animation_get (e->real.real) ? Qtrue : Qfalse;
358 }
359
360 /*
361  * call-seq:
362  *  edje.animation(true or false)
363  *
364  * Sets the animation state of <i>edje</i>.
365  */
366 static VALUE c_animation_set (VALUE self, VALUE val)
367 {
368         GET_OBJ (self, RbEdje, e);
369
370         CHECK_BOOL(val);
371
372         edje_object_animation_set (e->real.real, val == Qtrue);
373
374         return Qnil;
375 }
376
377 void Init_Edje (void)
378 {
379         cEdje = rb_define_class_under (mEdje, "Edje", cEvasObject);
380
381         rb_define_singleton_method (cEdje, "new", c_new, 1);
382         rb_define_method (cEdje, "freeze", c_freeze, 0);
383         rb_define_method (cEdje, "thaw", c_thaw, 0);
384         rb_define_method (cEdje, "load", c_load, 2);
385         rb_define_method (cEdje, "get_size_min", c_get_size_min, 0);
386         rb_define_method (cEdje, "get_size_max", c_get_size_max, 0);
387         rb_define_method (cEdje, "part_exists?", c_part_exists_get, 1);
388         rb_define_method (cEdje, "part", c_part_get, 1);
389         rb_define_method (cEdje, "on_text_changed", c_on_text_changed, 0);
390         rb_define_method (cEdje, "emit_signal", c_emit_signal, 2);
391         rb_define_method (cEdje, "on_signal", c_on_signal, 2);
392         rb_define_method (cEdje, "play?", c_play_get, 0);
393         rb_define_method (cEdje, "play=", c_play_set, 1);
394         rb_define_method (cEdje, "animation?", c_animation_get, 0);
395         rb_define_method (cEdje, "animation=", c_animation_set, 1);
396 }