Made EcoreEvas.new public for now.
[ruby-ecore.git] / src / ecore_evas / rb_ecore_evas.c
1 /*
2  * $Id: rb_ecore_evas.c 353 2006-02-10 17:00:24Z tilman $
3  *
4  * Copyright (C) 2004 ruby-ecore team (see AUTHORS)
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 #include <stdbool.h>
23
24 #include <Ecore.h>
25 #include <Ecore_Evas.h>
26 #include <evas/rb_evas.h>
27
28 #define __RB_ECORE_EVAS_C
29 #include "../ecore/rb_ecore.h"
30 #include "rb_ecore_evas_main.h"
31 #include "rb_ecore_evas.h"
32
33 #define RUBY_ECORE_EVAS_KEY "__RB_ECORE_EVAS_KEY"
34
35 #define CALLBACK_DEFINE_HANDLER(name) \
36         static void on_##name (Ecore_Evas *real) \
37         { \
38                 VALUE self; \
39                 VALUE cb; \
40 \
41                 self = (VALUE) ecore_evas_data_get (real, \
42                                                     RUBY_ECORE_EVAS_KEY); \
43                 GET_OBJ (self, RbEcoreEvas, ee); \
44 \
45                 cb = rb_hash_aref (ee->callbacks, rb_str_new2 (#name)); \
46                 rb_funcall (cb, rb_intern ("call"), 0); \
47         } \
48
49 #define CALLBACK_REG_HANDLER(name) \
50                 GET_OBJ (self, RbEcoreEvas, ee); \
51 \
52                 if (!rb_block_given_p ()) \
53                         return Qnil; \
54 \
55                 if (NIL_P (ee->callbacks)) \
56                         ee->callbacks = rb_hash_new (); \
57 \
58                 rb_hash_aset (ee->callbacks, rb_str_new2 (#name), \
59                               rb_block_proc ()); \
60 \
61                 ecore_evas_callback_##name##_set (ee->real, on_##name); \
62 \
63                 return Qnil;
64
65 VALUE cEcoreEvas;
66
67 /* called by the child classes */
68 void c_ecore_evas_mark (RbEcoreEvas *ee)
69 {
70         if (!NIL_P (ee->evas))
71                 rb_gc_mark (ee->evas);
72
73         if (!NIL_P (ee->callbacks))
74                 rb_gc_mark (ee->callbacks);
75 }
76
77 void c_ecore_evas_free (RbEcoreEvas *ee, bool free_mem)
78 {
79         if (ee->real)
80                 ecore_evas_free (ee->real);
81
82         ecore_evas_shutdown ();
83         ecore_shutdown ();
84
85         if (free_mem)
86                 free (ee);
87 }
88
89 /* :nodoc: */
90 static VALUE c_init (int argc, VALUE *argv, VALUE self)
91 {
92         GET_OBJ (self, RbEcoreEvas, ee);
93
94         ee->evas = Qnil;
95         ee->callbacks = Qnil;
96
97         ecore_evas_data_set (ee->real, RUBY_ECORE_EVAS_KEY, (void *) self);
98
99         return Qnil;
100 }
101
102 /* :nodoc: */
103 static VALUE c_inspect (VALUE self)
104 {
105         INSPECT (self, RbEcoreEvas);
106 }
107
108 /*
109  * call-seq:
110  *  ee.show => nil
111  *
112  * Shows <i>ee</i>.
113  */
114 static VALUE c_show (VALUE self)
115 {
116         GET_OBJ (self, RbEcoreEvas, ee);
117
118         ecore_evas_show (ee->real);
119
120         return Qnil;
121 }
122
123 /*
124  * call-seq:
125  *  ee.hide => nil
126  *
127  * Hides <i>ee</i>.
128  */
129 static VALUE c_hide (VALUE self)
130 {
131         GET_OBJ (self, RbEcoreEvas, ee);
132
133         ecore_evas_hide (ee->real);
134
135         return Qnil;
136 }
137
138 /*
139  * call-seq:
140  *  ee.visible? => true or false
141  *
142  * Returns true if <i>ee</i> is visible, else returns false.
143  */
144 static VALUE c_visible_get (VALUE self)
145 {
146         GET_OBJ (self, RbEcoreEvas, ee);
147
148         return ecore_evas_visibility_get (ee->real) ? Qtrue : Qfalse;
149 }
150
151 /*
152  * call-seq:
153  *   ee.raise => nil
154  *
155  * Raises <i>ee</i>.
156  */
157 static VALUE c_raise (VALUE self)
158 {
159         GET_OBJ (self, RbEcoreEvas, ee);
160
161         ecore_evas_raise (ee->real);
162
163         return Qnil;
164 }
165
166 /*
167  * call-seq:
168  *  ee.lower => nil
169  *
170  * Lowers <i>ee</i>.
171  */
172 static VALUE c_lower (VALUE self)
173 {
174         GET_OBJ (self, RbEcoreEvas, ee);
175
176         ecore_evas_lower (ee->real);
177
178         return Qnil;
179 }
180
181 /*
182  * call-seq:
183  *   ee.layer => fixnum
184  *
185  * Returns the layer of <i>ee</i>.
186  */
187 static VALUE c_layer_get (VALUE self)
188 {
189         GET_OBJ (self, RbEcoreEvas, ee);
190
191         return INT2FIX (ecore_evas_layer_get (ee->real));
192 }
193
194 /*
195  * call-seq:
196  *  ee.layer(fixnum) => fixnum
197  *
198  * Sets the layer of <i>ee</i>.
199  */
200 static VALUE c_layer_set (VALUE self, VALUE val)
201 {
202         GET_OBJ (self, RbEcoreEvas, ee);
203
204         Check_Type (val, T_FIXNUM);
205
206         ecore_evas_layer_set (ee->real, FIX2INT (val));
207
208         return Qnil;
209 }
210
211 /*
212  * call-seq:
213  *  ee.evas => evas
214  *
215  * Returns the <code>Evas::Evas</code> object for <i>ee</i>.
216  */
217 static VALUE c_evas_get (VALUE self)
218 {
219         GET_OBJ (self, RbEcoreEvas, ee);
220
221         if (NIL_P (ee->evas))
222                 ee->evas = TO_EVAS (self, ecore_evas_get (ee->real));
223
224         return ee->evas;
225 }
226
227 /*
228  * call-seq:
229  *  ee.geometry => array
230  *
231  * Returns an array containing the geometry of <i>ee</i>.
232  *
233  *  ee.move(150, 300)   #=> nil
234  *  ee.resize(200, 200) #=> nil
235  *  ee.geometry         #=> [150, 300, 200, 200]
236  */
237 static VALUE c_geometry_get (VALUE self)
238 {
239         int x = 0, y = 0, w = 0, h = 0;
240
241         GET_OBJ (self, RbEcoreEvas, ee);
242
243         ecore_evas_geometry_get (ee->real, &x, &y, &w, &h);
244
245         return rb_ary_new3 (4, INT2FIX (x), INT2FIX (y),
246                             INT2FIX (w), INT2FIX (h));
247 }
248
249 /*
250  * call-seq:
251  *  ee.get_size_min => array
252  *
253  * Returns an array containing the minimum size of <i>ee</i>.
254  *
255  *  ee.set_size_min(100, 200) #=> nil
256  *  ee.get_size_min           #=> [100, 200]
257  */
258 static VALUE c_get_size_min (VALUE self)
259 {
260         int w = 0, h = 0;
261
262         GET_OBJ (self, RbEcoreEvas, ee);
263
264         ecore_evas_size_min_get (ee->real, &w, &h);
265
266         return rb_ary_new3 (2, INT2FIX (w), INT2FIX (h));
267 }
268
269 /*
270  * call-seq:
271  *  ee.set_size_min(width, height) => nil
272  *
273  * Sets the minimum size of <i>ee</i>.
274  *
275  *  ee.set_size_min(100, 200) #=> nil
276  */
277 static VALUE c_set_size_min (VALUE self, VALUE w, VALUE h)
278 {
279         GET_OBJ (self, RbEcoreEvas, ee);
280
281         Check_Type (w, T_FIXNUM);
282         Check_Type (h, T_FIXNUM);
283
284         ecore_evas_size_min_set (ee->real, FIX2INT (w), FIX2INT (h));
285
286         return Qnil;
287 }
288
289 /*
290  * call-seq:
291  *  ee.get_size_max => array
292  *
293  * Returns an array containing the maximum size of <i>ee</i>.
294  *
295  *  ee.set_size_max(100, 200) #=> nil
296  *  ee.get_size_max           #=> [100, 200]
297  */
298 static VALUE c_get_size_max (VALUE self)
299 {
300         int w = 0, h = 0;
301
302         GET_OBJ (self, RbEcoreEvas, ee);
303
304         ecore_evas_size_max_get (ee->real, &w, &h);
305
306         return rb_ary_new3 (2, INT2FIX (w), INT2FIX (h));
307 }
308
309 /*
310  * call-seq:
311  *  ee.set_size_max(width, height) => nil
312  *
313  * Sets the maximum size of <i>ee</i>.
314  *
315  *  ee.set_size_max(100, 200) #=> nil
316  */
317 static VALUE c_set_size_max (VALUE self, VALUE w, VALUE h)
318 {
319         GET_OBJ (self, RbEcoreEvas, ee);
320
321         Check_Type (w, T_FIXNUM);
322         Check_Type (h, T_FIXNUM);
323
324         ecore_evas_size_max_set (ee->real, FIX2INT (w), FIX2INT (h));
325
326         return Qnil;
327 }
328
329 /*
330  * call-seq:
331  *  ee.move(x, y) => nil
332  *
333  * Moves <i>ee</i> to the coordinates specified in
334  * <i>x</i> and <i>y</i>.
335  *
336  *  ee.move(100, 200) #=> nil
337  */
338 static VALUE c_move (VALUE self, VALUE x, VALUE y)
339 {
340         GET_OBJ (self, RbEcoreEvas, ee);
341
342         Check_Type (x, T_FIXNUM);
343         Check_Type (y, T_FIXNUM);
344
345         ecore_evas_move (ee->real, FIX2INT (x), FIX2INT (y));
346
347         return Qnil;
348 }
349
350 /*
351  * call-seq:
352  *  ee.resize(width, height) => nil
353  *
354  * Resizes <i>ee</i> to width x height.
355  *
356  *  ee.resize(100, 200) #=> nil
357  */
358 static VALUE c_resize (VALUE self, VALUE w, VALUE h)
359 {
360         GET_OBJ (self, RbEcoreEvas, ee);
361
362         Check_Type (w, T_FIXNUM);
363         Check_Type (h, T_FIXNUM);
364
365         ecore_evas_resize (ee->real, FIX2INT (w), FIX2INT (h));
366
367         return Qnil;
368 }
369
370 /*
371  * call-seq:
372  *  ee.title => string
373  *
374  * Returns the title of <i>ee</i>.
375  */
376 static VALUE c_title_get (VALUE self)
377 {
378         const char *tmp;
379
380         GET_OBJ (self, RbEcoreEvas, ee);
381
382         if (!(tmp = ecore_evas_title_get (ee->real)))
383                 return Qnil;
384         else
385                 return rb_str_new2 (tmp);
386 }
387
388 /*
389  * call-seq:
390  *  ee.title(string)
391  *
392  * Sets the title of <i>ee</i>.
393  */
394 static VALUE c_title_set (VALUE self, VALUE val)
395 {
396         GET_OBJ (self, RbEcoreEvas, ee);
397
398         Check_Type (val, T_STRING);
399
400         ecore_evas_title_set (ee->real, StringValuePtr (val));
401
402         return Qnil;
403 }
404
405 /*
406  * call-seq:
407  *  ee.borderless? => true or false
408  *
409  * Returns true if <i>ee</i> is borderless, else returns false.
410  */
411 static VALUE c_borderless_get (VALUE self)
412 {
413         GET_OBJ (self, RbEcoreEvas, ee);
414
415         return ecore_evas_borderless_get (ee->real) ? Qtrue : Qfalse;
416 }
417
418 /*
419  * call-seq:
420  *  ee.borderless(true or false)
421  *
422  * Sets whether <i>ee</i> is borderless or not.
423  */
424 static VALUE c_borderless_set (VALUE self, VALUE val)
425 {
426         GET_OBJ (self, RbEcoreEvas, ee);
427
428         CHECK_BOOL (val);
429
430         ecore_evas_borderless_set (ee->real, val == Qtrue);
431
432         return Qnil;
433 }
434
435 /*
436  * call-seq:
437  *  ee.shaped? => true or false
438  *
439  * Returns true if <i>ee</i> is shaped, else returns false.
440  */
441 static VALUE c_shaped_get (VALUE self)
442 {
443         GET_OBJ (self, RbEcoreEvas, ee);
444
445         return ecore_evas_shaped_get (ee->real) ? Qtrue : Qfalse;
446 }
447
448 /*
449  * call-seq:
450  *  ee.shaped(true or false)
451  *
452  * Sets whether <i>ee</i> is shaped or not.
453  */
454 static VALUE c_shaped_set (VALUE self, VALUE val)
455 {
456         GET_OBJ (self, RbEcoreEvas, ee);
457
458         CHECK_BOOL (val);
459
460         ecore_evas_shaped_set (ee->real, val == Qtrue);
461
462         return Qnil;
463 }
464
465 /*
466  * call-seq:
467  *  ee.sticky? => true or false
468  *
469  * Returns true if <i>ee</i> is sticky, else returns false.
470  */
471 static VALUE c_sticky_get (VALUE self)
472 {
473         GET_OBJ (self, RbEcoreEvas, ee);
474
475         return ecore_evas_sticky_get (ee->real) ? Qtrue : Qfalse;
476 }
477
478 /*
479  * call-seq:
480  *  ee.sticky(true or false)
481  *
482  * Sets whether <i>ee</i> is sticky or not.
483  */
484 static VALUE c_sticky_set (VALUE self, VALUE val)
485 {
486         GET_OBJ (self, RbEcoreEvas, ee);
487
488         CHECK_BOOL (val);
489
490         ecore_evas_sticky_set (ee->real, val == Qtrue);
491
492         return Qnil;
493 }
494
495 /*
496  * call-seq:
497  *  ee.rotation => fixnum
498  *
499  * Returns the rotation of <i>ee</i>.
500  */
501 static VALUE c_rotation_get (VALUE self)
502 {
503         GET_OBJ (self, RbEcoreEvas, ee);
504
505         return INT2FIX (ecore_evas_rotation_get (ee->real));
506 }
507
508 /*
509  * call-seq:
510  *  ee.rotation(fixnum)
511  *
512  * Sets the rotation of <i>ee</i>.
513  */
514 static VALUE c_rotation_set (VALUE self, VALUE val)
515 {
516         GET_OBJ (self, RbEcoreEvas, ee);
517
518         Check_Type (val, T_FIXNUM);
519
520         ecore_evas_rotation_set (ee->real, FIX2INT (val));
521
522         return Qnil;
523 }
524
525 static VALUE c_name_class_get (VALUE self)
526 {
527         const char *name = NULL, *klass = NULL;
528
529         GET_OBJ (self, RbEcoreEvas, ee);
530
531         ecore_evas_name_class_get (ee->real, &name, &klass);
532
533         return rb_ary_new3 (2, name ? rb_str_new2 (name) : Qnil,
534                             klass ? rb_str_new2 (klass) : Qnil);
535 }
536
537 static VALUE c_name_class_set (VALUE self, VALUE ary)
538 {
539         VALUE s1, s2;
540
541         GET_OBJ (self, RbEcoreEvas, ee);
542
543         Check_Type (ary, T_ARRAY);
544
545         s1 = rb_ary_shift (ary);
546         s2 = rb_ary_shift (ary);
547
548         StringValue (s1);
549         StringValue (s2);
550
551         ecore_evas_name_class_set (ee->real, StringValuePtr (s1),
552                                    StringValuePtr (s2));
553
554         return Qnil;
555 }
556
557 /* FIXME: this is unsafe!
558  * :nodoc:
559  */
560 static VALUE c_delete (VALUE self)
561 {
562         GET_OBJ (self, RbEcoreEvas, ee);
563
564         /* reap our children */
565         rb_gc_start ();
566
567         ecore_evas_free (ee->real);
568         ee->real = NULL;
569
570         return Qnil;
571 }
572
573 CALLBACK_DEFINE_HANDLER (resize);
574 CALLBACK_DEFINE_HANDLER (move);
575 CALLBACK_DEFINE_HANDLER (show);
576 CALLBACK_DEFINE_HANDLER (hide);
577 CALLBACK_DEFINE_HANDLER (delete_request);
578 CALLBACK_DEFINE_HANDLER (destroy);
579 CALLBACK_DEFINE_HANDLER (focus_in);
580 CALLBACK_DEFINE_HANDLER (focus_out);
581 CALLBACK_DEFINE_HANDLER (mouse_in);
582 CALLBACK_DEFINE_HANDLER (mouse_out);
583 CALLBACK_DEFINE_HANDLER (pre_render);
584 CALLBACK_DEFINE_HANDLER (post_render);
585
586 /*
587  * call-seq:
588  *  ee.on_resize { block } => nil
589  *
590  * Sets the handler for the resize event.
591  */
592 static VALUE c_on_resize (VALUE self)
593 {
594         CALLBACK_REG_HANDLER (resize);
595 }
596
597 /*
598  * call-seq:
599  *  ee.on_move { block } => nil
600  *
601  * Sets the handler for the move event.
602  */
603 static VALUE c_on_move (VALUE self)
604 {
605         CALLBACK_REG_HANDLER (move);
606 }
607
608 /*
609  * call-seq:
610  *  ee.on_show { block } => nil
611  *
612  * Sets the handler for the show event.
613  */
614 static VALUE c_on_show (VALUE self)
615 {
616         CALLBACK_REG_HANDLER (show);
617 }
618
619 /*
620  * call-seq:
621  *  ee.on_hide { block } => nil
622  *
623  * Sets the handler for the hide event.
624  */
625 static VALUE c_on_hide (VALUE self)
626 {
627         CALLBACK_REG_HANDLER (hide);
628 }
629
630 /*
631  * call-seq:
632  *  ee.on_delete_request { block } => nil
633  *
634  * Sets the handler for the delete request event.
635  */
636 static VALUE c_on_delete_request (VALUE self)
637 {
638         CALLBACK_REG_HANDLER (delete_request);
639 }
640
641 /*
642  * call-seq:
643  *  ee.on_destroy { block } => nil
644  *
645  * Sets the handler for the destroy event.
646  */
647 static VALUE c_on_destroy (VALUE self)
648 {
649         CALLBACK_REG_HANDLER (destroy);
650 }
651
652 /*
653  * call-seq:
654  *  ee.on_focus_in { block } => nil
655  *
656  * Sets the handler for the focus in event.
657  */
658 static VALUE c_on_focus_in (VALUE self)
659 {
660         CALLBACK_REG_HANDLER (focus_in);
661 }
662
663 /*
664  * call-seq:
665  *  ee.on_focus_out { block } => nil
666  *
667  * Sets the handler for the focus out event.
668  */
669 static VALUE c_on_focus_out (VALUE self)
670 {
671         CALLBACK_REG_HANDLER (focus_out);
672 }
673
674 /*
675  * call-seq:
676  *  ee.on_mouse_in { block } => nil
677  *
678  * Sets the handler for the mouse in event.
679  */
680 static VALUE c_on_mouse_in (VALUE self)
681 {
682         CALLBACK_REG_HANDLER (mouse_in);
683 }
684
685 /*
686  * call-seq:
687  *  ee.on_mouse_out { block } => nil
688  *
689  * Sets the handler for the mouse out event.
690  */
691 static VALUE c_on_mouse_out (VALUE self)
692 {
693         CALLBACK_REG_HANDLER (mouse_out);
694 }
695
696 /*
697  * call-seq:
698  *  ee.on_pre_render { block } => nil
699  *
700  * Sets the handler for the pre render event.
701  */
702 static VALUE c_on_pre_render (VALUE self)
703 {
704         CALLBACK_REG_HANDLER (pre_render);
705 }
706
707 /*
708  * call-seq:
709  *  ee.on_post_render { block } => nil
710  *
711  * Sets the handler for the post render event.
712  */
713 static VALUE c_on_post_render (VALUE self)
714 {
715         CALLBACK_REG_HANDLER (post_render);
716 }
717
718 void Init_EcoreEvas (void)
719 {
720         cEcoreEvas = rb_define_class_under (mEvas, "EcoreEvas", rb_cObject);
721
722         rb_define_method (cEcoreEvas, "initialize", c_init, -1);
723         rb_define_method (cEcoreEvas, "inspect", c_inspect, 0);
724         rb_define_method (cEcoreEvas, "delete", c_delete, 0);
725         rb_define_method (cEcoreEvas, "show", c_show, 0);
726         rb_define_method (cEcoreEvas, "hide", c_hide, 0);
727         rb_define_method (cEcoreEvas, "visible?", c_visible_get, 0);
728         rb_define_method (cEcoreEvas, "raise", c_raise, 0);
729         rb_define_method (cEcoreEvas, "lower", c_lower, 0);
730         rb_define_method (cEcoreEvas, "layer", c_layer_get, 0);
731         rb_define_method (cEcoreEvas, "layer=", c_layer_set, 1);
732         rb_define_method (cEcoreEvas, "evas", c_evas_get, 0);
733         rb_define_method (cEcoreEvas, "geometry", c_geometry_get, 0);
734         rb_define_method (cEcoreEvas, "get_size_min", c_get_size_min, 0);
735         rb_define_method (cEcoreEvas, "set_size_min", c_set_size_min, 2);
736         rb_define_method (cEcoreEvas, "get_size_max", c_get_size_max, 0);
737         rb_define_method (cEcoreEvas, "set_size_max", c_set_size_max, 2);
738         rb_define_method (cEcoreEvas, "move", c_move, 2);
739         rb_define_method (cEcoreEvas, "resize", c_resize, 2);
740         rb_define_method (cEcoreEvas, "title", c_title_get, 0);
741         rb_define_method (cEcoreEvas, "title=", c_title_set, 1);
742         rb_define_method (cEcoreEvas, "borderless?", c_borderless_get, 0);
743         rb_define_method (cEcoreEvas, "borderless=", c_borderless_set, 1);
744         rb_define_method (cEcoreEvas, "shaped?", c_shaped_get, 0);
745         rb_define_method (cEcoreEvas, "shaped=", c_shaped_set, 1);
746         rb_define_method (cEcoreEvas, "sticky?", c_sticky_get, 0);
747         rb_define_method (cEcoreEvas, "sticky=", c_sticky_set, 1);
748         rb_define_method (cEcoreEvas, "rotation", c_rotation_get, 0);
749         rb_define_method (cEcoreEvas, "rotation=", c_rotation_set, 1);
750         rb_define_method (cEcoreEvas, "name_class", c_name_class_get, 0);
751         rb_define_method (cEcoreEvas, "name_class=", c_name_class_set, 1);
752
753         rb_define_method (cEcoreEvas, "on_resize", c_on_resize, 0);
754         rb_define_method (cEcoreEvas, "on_move", c_on_move, 0);
755         rb_define_method (cEcoreEvas, "on_show", c_on_show, 0);
756         rb_define_method (cEcoreEvas, "on_hide", c_on_hide, 0);
757         rb_define_method (cEcoreEvas, "on_delete_request", c_on_delete_request, 0);
758         rb_define_method (cEcoreEvas, "on_destroy", c_on_destroy, 0);
759         rb_define_method (cEcoreEvas, "on_focus_in", c_on_focus_in, 0);
760         rb_define_method (cEcoreEvas, "on_focus_out", c_on_focus_out, 0);
761         rb_define_method (cEcoreEvas, "on_mouse_in", c_on_mouse_in, 0);
762         rb_define_method (cEcoreEvas, "on_mouse_out", c_on_mouse_out, 0);
763         rb_define_method (cEcoreEvas, "on_pre_render", c_on_pre_render, 0);
764         rb_define_method (cEcoreEvas, "on_post_render", c_on_post_render, 0);
765 }