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