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