]> git.donarmstrong.com Git - lilypond.git/blob - lily/axis-group-interface.cc
release: 1.3.73
[lilypond.git] / lily / axis-group-interface.cc
1 /*   
2   axis-group-interface.cc --  implement Axis_group_interface
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 2000 Han-Wen Nienhuys <hanwen@cs.uu.nl>
7   
8  */
9
10 #include "axis-group-interface.hh"
11 #include "score-element.hh"
12
13 void
14 Axis_group_interface::add_element (Score_element*me,Score_element *e)
15 {
16   for (SCM ax = me->get_elt_property ("axes"); ax != SCM_EOL ; ax = gh_cdr (ax))
17     {
18       Axis a = (Axis) gh_scm2int (gh_car (ax));
19       
20       if (!e->parent_l (a))
21         e->set_parent (me, a);
22     }
23
24   Pointer_group_interface (me).add_element (e);
25   me->add_dependency (e);
26 }
27
28 bool
29 Axis_group_interface::axis_b (Score_element*me,Axis a )
30 {
31   return me->has_extent_callback_b (group_extent_callback, a);
32 }
33
34 Interval
35 Axis_group_interface::relative_group_extent (Axis a, Score_element *common, SCM elts)
36 {
37   Interval r;
38   for (SCM s = elts; gh_pair_p (s); s = gh_cdr (s))
39     {
40       Score_element * se = unsmob_element (gh_car (s));
41       Interval dims = se->extent (a);
42       if (!dims.empty_b ())
43         r.unite (dims + se->relative_coordinate (common, a));
44     }
45   return r;
46 }
47
48 Interval
49 Axis_group_interface::group_extent_callback (Score_element *me, Axis a)
50 {
51   Score_element * common =(Score_element*) me;
52
53   for (SCM s = me->get_elt_property ("elements"); gh_pair_p (s); s = gh_cdr (s))
54     {
55       Score_element * se = unsmob_element (gh_car (s));
56       common = se->common_refpoint (common, a);
57     }
58
59   Real my_coord = me->relative_coordinate (common, a);
60   Interval r (relative_group_extent (a, common, me->get_elt_property ("elements")));
61
62   return r - my_coord;
63 }
64
65
66
67 void
68 Axis_group_interface::set_axes (Score_element*me,Axis a1, Axis a2)
69 {
70   // set_interface () ?
71   SCM sa1= gh_int2scm (a1);
72   SCM sa2 = gh_int2scm (a2);
73
74   SCM prop = me->get_elt_property ("axes");
75   
76   if (!gh_pair_p (prop)
77       || scm_memq (sa1, prop) == SCM_BOOL_F
78       || scm_memq (sa2, prop) == SCM_BOOL_F)
79     {
80       SCM ax = gh_cons (sa1, SCM_EOL);
81       if (a1 != a2)
82         ax= gh_cons (sa2, ax);
83       me->set_elt_property ("axes", ax);
84     }
85
86   if (a1 != X_AXIS && a2 != X_AXIS)
87     me->set_extent_callback (0, X_AXIS);
88   if (a1 != Y_AXIS && a2 != Y_AXIS)
89     me->set_extent_callback (0, Y_AXIS);
90   
91   me->set_extent_callback (Axis_group_interface::group_extent_callback,a1);
92   me->set_extent_callback (Axis_group_interface::group_extent_callback,a2);
93 }
94
95 Link_array<Score_element> 
96 Axis_group_interface::get_children (Score_element*me)
97 {
98   Link_array<Score_element> childs;
99   childs.push (me) ;
100
101   if (!has_interface (me))
102     return childs;
103   
104   for (SCM ep = me->get_elt_property ("elements"); gh_pair_p (ep); ep = gh_cdr (ep))
105     {
106       Score_element* e = unsmob_element (gh_car (ep));
107       if (e)
108         childs.concat (Axis_group_interface::get_children (e));
109     }
110   
111   return childs;
112 }
113
114 bool
115 Axis_group_interface::has_interface (Score_element*me)
116 {
117   return me && me->has_interface (ly_symbol2scm ("axis-group-interface"));
118 }
119
120
121
122 void
123 Axis_group_interface::set_interface (Score_element*me)
124 {
125   if (!has_interface (me))
126     {
127       me->set_interface (ly_symbol2scm ("axis-group-interface"));      
128     }
129 }