]> git.donarmstrong.com Git - lilypond.git/blob - lily/axis-group-interface.cc
release: 1.3.56
[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 #include "dimension-cache.hh"
13
14 Axis_group_interface::Axis_group_interface (Score_element*s)
15 {
16   elt_l_ = s;
17 }
18
19 Axis_group_interface
20 Axis_group_interface (Score_element*s)
21 {
22   return Axis_group_interface (s);
23 }
24
25 void
26 Axis_group_interface::add_element (Score_element *e)
27 {
28   for (SCM ax = elt_l_->get_elt_property ("axes"); ax != SCM_EOL ; ax = gh_cdr (ax))
29     {
30       Axis a = (Axis) gh_scm2int (gh_car (ax));
31       
32       if (!e->parent_l (a))
33         e->set_parent (elt_l_, a);
34     }
35
36   Pointer_group_interface (elt_l_).add_element (e);
37   elt_l_->add_dependency (e);
38 }
39
40
41 bool
42 Axis_group_interface::axis_b (Axis a )const
43 {
44   return elt_l_->has_extent_callback_b (group_extent_callback, a);
45 }
46
47 Interval
48 Axis_group_interface::relative_group_extent (Axis a, Score_element *common, SCM elts)
49 {
50   Interval r;
51   for (SCM s = elts; gh_pair_p (s); s = gh_cdr (s))
52     {
53       Score_element * se = unsmob_element (gh_car (s));
54       Interval dims = se->extent (a);
55       if (!dims.empty_b ())
56         r.unite (dims + se->relative_coordinate (common, a));
57     }
58   return r;
59 }
60
61 Interval
62 Axis_group_interface::group_extent_callback (Score_element const*me, Axis a)
63 {
64   Score_element * common =(Score_element*) me;
65
66   for (SCM s = me->get_elt_pointer ("elements"); gh_pair_p (s); s = gh_cdr (s))
67     {
68       Score_element * se = unsmob_element (gh_car (s));
69       common = se->common_refpoint (common, a);
70     }
71
72   Real my_coord = me->relative_coordinate (common, a);
73   Interval r (relative_group_extent (a, common, me->get_elt_pointer ("elements")));
74
75   return r - my_coord;
76 }
77
78 void
79 Axis_group_interface::set_interface ()
80 {
81   if (!has_interface_b ())
82     {
83       elt_l_->set_elt_pointer ("elements", SCM_EOL);
84
85
86       Group_interface (elt_l_, "interfaces").add_thing (ly_symbol2scm ("Axis_group"));
87     }
88 }
89
90 void
91 Axis_group_interface::set_axes (Axis a1, Axis a2)
92 {
93   // set_interface () ?
94   SCM sa1= gh_int2scm (a1);
95   SCM sa2 = gh_int2scm (a2);
96
97   SCM prop = elt_l_->get_elt_property ("axes");
98   
99   if (prop == SCM_UNDEFINED
100       || scm_memq (sa1, prop) == SCM_BOOL_F
101       || scm_memq (sa2, prop) == SCM_BOOL_F)
102     {
103       SCM ax = gh_cons (sa1, SCM_EOL);
104       if (a1 != a2)
105         ax= gh_cons (sa2, ax);
106       elt_l_->set_elt_property ("axes", ax);
107     }
108
109   if (a1 != X_AXIS && a2 != X_AXIS)
110     elt_l_->set_extent_callback (0, X_AXIS);
111   if (a1 != Y_AXIS && a2 != Y_AXIS)
112     elt_l_->set_extent_callback (0, Y_AXIS);
113   
114   elt_l_->set_extent_callback (Axis_group_interface::group_extent_callback,a1);
115   elt_l_->set_extent_callback (Axis_group_interface::group_extent_callback,a2);
116 }
117
118 Link_array<Score_element> 
119 Axis_group_interface::get_children ()
120 {
121   Link_array<Score_element> childs;
122   childs.push (elt_l_) ;
123
124   if (!has_interface_b ())
125     return childs;
126   
127   for (SCM ep = elt_l_->get_elt_pointer ("elements"); gh_pair_p (ep); ep = gh_cdr (ep))
128     {
129       Score_element* e = unsmob_element (gh_car (ep));
130       if (e)
131         childs.concat (Axis_group_interface (e).get_children ());
132     }
133   
134   return childs;
135 }
136
137 bool
138 Axis_group_interface::has_interface_b ()
139 {
140   SCM ifs = elt_l_->get_elt_property ("interfaces");
141
142   if (!gh_pair_p (ifs ))
143     return false;
144   return scm_memq (ly_symbol2scm ("Axis_group"),ifs)  != SCM_BOOL_F;
145 }
146
147