]> git.donarmstrong.com Git - lilypond.git/blob - lily/piano-pedal-engraver.cc
patch::: 1.3.108.jcn3
[lilypond.git] / lily / piano-pedal-engraver.cc
1 /*   
2   piano-pedal-engraver.cc --  implement Piano_pedal_engraver
3   
4   source file of the GNU LilyPond music typesetter
5   
6   (c) 2000 Jan Nieuwenhuizen <janneke@gnu.org>
7  */
8
9 #include "engraver.hh"
10 #include "musical-request.hh"
11 #include "score-element.hh"
12 #include "item.hh"
13 #include "lily-guile.hh"
14 #include "rhythmic-head.hh"
15 #include "stem.hh"
16 #include "side-position-interface.hh"
17 #include "staff-symbol-referencer.hh"
18 #include "item.hh"
19
20
21
22
23
24 /**
25    engrave Piano pedals symbols.
26  */
27 class Piano_pedal_engraver : public Engraver
28 {
29 public:
30   VIRTUAL_COPY_CONS (Translator);
31   Piano_pedal_engraver ();
32   ~Piano_pedal_engraver ();
33 protected:
34   virtual void do_creation_processing ();
35   virtual bool do_try_music (Music*);
36   void deprecated_process_music ();
37   virtual void do_pre_move_processing ();
38   virtual void do_post_move_processing ();
39   virtual void acknowledge_element (Score_element_info);
40   virtual void process_acknowledged ();
41
42 private:
43   struct Pedal_info
44   {
45     char const * name_;
46     Span_req* start_req_l_;
47     Drul_array<Span_req*> req_l_drul_;
48     Item* item_p_;
49   };
50
51
52   Pedal_info *info_list_;
53 };
54
55 ADD_THIS_TRANSLATOR (Piano_pedal_engraver);
56
57 Piano_pedal_engraver::Piano_pedal_engraver ()
58 {
59   info_list_ = 0;
60 }
61 void
62 Piano_pedal_engraver::do_creation_processing()
63 {
64   info_list_ = new Pedal_info[4];
65   Pedal_info *p = info_list_;
66
67
68   char * names [] = { "Sostenuto", "Sustain", "UnaChorda", 0  };
69   char **np = names ;
70   do
71     {
72       p->name_ = *np;
73       p->item_p_ = 0;
74       p->req_l_drul_[START] = 0;
75       p->req_l_drul_[STOP] = 0;
76       p->start_req_l_ = 0;
77
78       p++;
79     }
80   while (*(np ++));
81 }
82
83 Piano_pedal_engraver::~Piano_pedal_engraver()
84 {
85   delete[] info_list_;
86 }
87
88 /*
89   Urg: Code dup
90   I'm a script
91  */
92 void
93 Piano_pedal_engraver::acknowledge_element (Score_element_info info)
94 {
95   for (Pedal_info*p = info_list_; p && p->name_; p ++)
96     {
97       if (p->item_p_)
98         {
99           if (Rhythmic_head::has_interface (info.elem_l_))
100             {
101               Side_position::add_support (p->item_p_, info.elem_l_);
102
103               if (Side_position::get_axis(p->item_p_) == X_AXIS
104                   && !p->item_p_->parent_l (Y_AXIS))
105                 p->item_p_->set_parent (info.elem_l_, Y_AXIS);
106             }
107           if (Stem::has_interface (info.elem_l_))
108             {
109               Side_position::add_support (p->item_p_,info.elem_l_);
110             }
111         }
112     }
113 }
114
115 bool
116 Piano_pedal_engraver::do_try_music (Music *m)
117 {
118   if (Span_req * s = dynamic_cast<Span_req*>(m))
119     {
120       for (Pedal_info*p = info_list_; p->name_; p ++)
121         {
122           if (scm_equal_p (s->get_mus_property ("span-type"),
123                            ly_str02scm (p->name_))==SCM_BOOL_T)
124             {
125               p->req_l_drul_[s->get_span_dir()] = s;
126               return true;
127             }
128         }
129     }
130   return false;
131 }
132
133 void
134 Piano_pedal_engraver::process_acknowledged ()
135 {
136   deprecated_process_music ();
137 }
138
139 void
140 Piano_pedal_engraver::deprecated_process_music ()
141 {
142   for (Pedal_info*p = info_list_; p && p->name_; p ++)
143     {
144       if (p->item_p_)
145         continue;
146       SCM s = SCM_EOL;
147       if (p->req_l_drul_[STOP] && p->req_l_drul_[START])
148         {
149           if (!p->start_req_l_)
150             {
151               p->req_l_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: %s",  p->name_ ));
152             }
153           else
154             {
155               s = get_property (("stopStart" + String (p->name_ )).ch_C());
156             }
157           p->start_req_l_ = p->req_l_drul_[START];
158         }
159       else if (p->req_l_drul_[STOP])
160         {
161           if (!p->start_req_l_)
162             {
163               p->req_l_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: %s", p->name_ ));
164             }
165           else
166             {
167               s = get_property (("stop" + String (p->name_ )).ch_C());
168             }
169           p->start_req_l_ = 0;
170         }
171       else if (p->req_l_drul_[START])
172         {
173           p->start_req_l_ = p->req_l_drul_[START];
174           s = get_property (("start" + String (p->name_ )).ch_C());
175         }
176
177       if (gh_string_p (s))
178         {
179           String propname = String (p->name_) + "Pedal";
180           p->item_p_ = new Item (get_property (propname.ch_C()));
181           p->item_p_->set_elt_property ("text", s);
182
183           announce_element (p->item_p_,
184                             p->req_l_drul_[START]
185                             ? p->req_l_drul_[START]
186                             : p->req_l_drul_[STOP]);
187         }
188     }
189 }
190
191 void
192 Piano_pedal_engraver::do_pre_move_processing ()
193 {
194   Item * sustain = 0;
195   for (Pedal_info*p = info_list_; p->name_; p ++)
196     {
197       if (p->name_ == String ("Sustain"))
198         sustain = p->item_p_;
199     }
200
201   for (Pedal_info*p = info_list_; p->name_; p ++)
202     {
203       if (p->item_p_)
204         {
205           Side_position::add_staff_support (p->item_p_);
206           /*
207             Hmm.
208           */
209           if (p->name_ != String ("Sustain"))
210             {
211               if (sustain)
212                 {
213                   Side_position::add_support (p->item_p_,sustain);
214                 }
215             }
216           typeset_element (p->item_p_);
217         }
218       p->item_p_ = 0;
219     }
220 }
221
222 void
223 Piano_pedal_engraver::do_post_move_processing ()
224 {
225   for (Pedal_info*p = info_list_; p->name_; p ++)
226     {
227       p->req_l_drul_[STOP] = 0;
228       p->req_l_drul_[START] = 0;
229     }
230 }