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