]> git.donarmstrong.com Git - lilypond.git/blob - lily/piano-pedal-engraver.cc
release: 1.3.105
[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   virtual void do_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
41 private:
42   struct Pedal_info
43   {
44     char const * name_;
45     Span_req* start_req_l_;
46     Drul_array<Span_req*> req_l_drul_;
47     Item* item_p_;
48   };
49
50
51   Pedal_info *info_list_;
52 };
53
54 ADD_THIS_TRANSLATOR (Piano_pedal_engraver);
55
56 Piano_pedal_engraver::Piano_pedal_engraver ()
57 {
58   info_list_ = 0;
59 }
60 void
61 Piano_pedal_engraver::do_creation_processing()
62 {
63   info_list_ = new Pedal_info[4];
64   Pedal_info *p = info_list_;
65
66
67   char * names [] = { "Sostenuto", "Sustain", "UnaChorda", 0  };
68   char **np = names ;
69   do
70     {
71       p->name_ = *np;
72       p->item_p_ = 0;
73       p->req_l_drul_[START] = 0;
74       p->req_l_drul_[STOP] = 0;
75       p->start_req_l_ = 0;
76
77       p++;
78     }
79   while (*(np ++));
80 }
81
82 Piano_pedal_engraver::~Piano_pedal_engraver()
83 {
84   delete[] info_list_;
85 }
86
87 /*
88   Urg: Code dup
89   I'm a script
90  */
91 void
92 Piano_pedal_engraver::acknowledge_element (Score_element_info info)
93 {
94   for (Pedal_info*p = info_list_; p->name_; p ++)
95     {
96       if (p->item_p_)
97         {
98           if (Rhythmic_head::has_interface (info.elem_l_))
99             {
100               Side_position::add_support (p->item_p_, info.elem_l_);
101
102               if (Side_position::get_axis(p->item_p_) == X_AXIS
103                   && !p->item_p_->parent_l (Y_AXIS))
104                 p->item_p_->set_parent (info.elem_l_, Y_AXIS);
105             }
106           if (Stem::has_interface (info.elem_l_))
107             {
108               Side_position::add_support (p->item_p_,info.elem_l_);
109             }
110         }
111     }
112 }
113
114 bool
115 Piano_pedal_engraver::do_try_music (Music *m)
116 {
117   if (Span_req * s = dynamic_cast<Span_req*>(m))
118     {
119       for (Pedal_info*p = info_list_; p->name_; p ++)
120         {
121           if (scm_equal_p (s->get_mus_property ("span-type"),
122                            ly_str02scm (p->name_))==SCM_BOOL_T)
123             {
124               p->req_l_drul_[s->get_span_dir()] = s;
125               return true;
126             }
127         }
128     }
129   return false;
130 }
131
132 void
133 Piano_pedal_engraver::do_process_music ()
134 {
135   for (Pedal_info*p = info_list_; p->name_; p ++)
136     {
137       SCM s = SCM_UNDEFINED;
138       if (p->req_l_drul_[STOP] && p->req_l_drul_[START])
139         {
140           if (!p->start_req_l_)
141             {
142               p->req_l_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: %s",  p->name_ ));
143             }
144           else
145             {
146               s = get_property (("stopStart" + String (p->name_ )).ch_C());
147             }
148           p->start_req_l_ = p->req_l_drul_[START];
149         }
150       else if (p->req_l_drul_[STOP])
151         {
152           if (!p->start_req_l_)
153             {
154               p->req_l_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: %s", p->name_ ));
155             }
156           else
157             {
158               s = get_property (("stop" + String (p->name_ )).ch_C());
159             }
160           p->start_req_l_ = 0;
161         }
162       else if (p->req_l_drul_[START])
163         {
164           p->start_req_l_ = p->req_l_drul_[START];
165           s = get_property (("start" + String (p->name_ )).ch_C());
166         }
167
168       if (gh_string_p (s))
169         {
170           String propname = String (p->name_) + "Pedal";
171           p->item_p_ = new Item (get_property (propname.ch_C()));
172           p->item_p_->set_elt_property ("text", s);
173
174           announce_element (p->item_p_,
175                             p->req_l_drul_[START]
176                             ? p->req_l_drul_[START]
177                             : p->req_l_drul_[STOP]);
178         }
179     }
180 }
181
182 void
183 Piano_pedal_engraver::do_pre_move_processing ()
184 {
185   Item * sustain = 0;
186   for (Pedal_info*p = info_list_; p->name_; p ++)
187     {
188       if (p->name_ == String ("Sustain"))
189         sustain = p->item_p_;
190     }
191
192   for (Pedal_info*p = info_list_; p->name_; p ++)
193     {
194       if (p->item_p_)
195         {
196           Side_position::add_staff_support (p->item_p_);
197           /*
198             Hmm.
199           */
200           if (p->name_ != String ("Sustain"))
201             {
202               if (sustain)
203                 {
204                   Side_position::add_support (p->item_p_,sustain);
205                 }
206             }
207           typeset_element (p->item_p_);
208         }
209       p->item_p_ = 0;
210     }
211 }
212
213 void
214 Piano_pedal_engraver::do_post_move_processing ()
215 {
216   for (Pedal_info*p = info_list_; p->name_; p ++)
217     {
218       p->req_l_drul_[STOP] = 0;
219       p->req_l_drul_[START] = 0;
220     }
221 }