]> git.donarmstrong.com Git - lilypond.git/blob - lily/piano-pedal-engraver.cc
release: 1.3.103
[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 (s->span_type_str_ == p->name_)
122             {
123               p->req_l_drul_[s->get_span_dir()] = s;
124               return true;
125             }
126         }
127     }
128   return false;
129 }
130
131 void
132 Piano_pedal_engraver::do_process_music ()
133 {
134   for (Pedal_info*p = info_list_; p->name_; p ++)
135     {
136       SCM s = SCM_UNDEFINED;
137       if (p->req_l_drul_[STOP] && p->req_l_drul_[START])
138         {
139           if (!p->start_req_l_)
140             {
141               p->req_l_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: %s",  p->name_ ));
142             }
143           else
144             {
145               s = get_property (("stopStart" + String (p->name_ )).ch_C());
146             }
147           p->start_req_l_ = p->req_l_drul_[START];
148         }
149       else if (p->req_l_drul_[STOP])
150         {
151           if (!p->start_req_l_)
152             {
153               p->req_l_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: %s", p->name_ ));
154             }
155           else
156             {
157               s = get_property (("stop" + String (p->name_ )).ch_C());
158             }
159           p->start_req_l_ = 0;
160         }
161       else if (p->req_l_drul_[START])
162         {
163           p->start_req_l_ = p->req_l_drul_[START];
164           s = get_property (("start" + String (p->name_ )).ch_C());
165         }
166
167       if (gh_string_p (s))
168         {
169           String propname = String (p->name_) + "Pedal";
170           p->item_p_ = new Item (get_property (propname.ch_C()));
171           p->item_p_->set_elt_property ("text", s);
172
173           announce_element (p->item_p_,
174                             p->req_l_drul_[START]
175                             ? p->req_l_drul_[START]
176                             : p->req_l_drul_[STOP]);
177         }
178     }
179 }
180
181 void
182 Piano_pedal_engraver::do_pre_move_processing ()
183 {
184   Item * sustain = 0;
185   for (Pedal_info*p = info_list_; p->name_; p ++)
186     {
187       if (p->name_ == String ("Sustain"))
188         sustain = p->item_p_;
189     }
190
191   for (Pedal_info*p = info_list_; p->name_; p ++)
192     {
193       if (p->item_p_)
194         {
195           Side_position::add_staff_support (p->item_p_);
196           /*
197             Hmm.
198           */
199           if (p->name_ != String ("Sustain"))
200             {
201               if (sustain)
202                 {
203                   Side_position::add_support (p->item_p_,sustain);
204                 }
205             }
206           typeset_element (p->item_p_);
207         }
208       p->item_p_ = 0;
209     }
210 }
211
212 void
213 Piano_pedal_engraver::do_post_move_processing ()
214 {
215   for (Pedal_info*p = info_list_; p->name_; p ++)
216     {
217       p->req_l_drul_[STOP] = 0;
218       p->req_l_drul_[START] = 0;
219     }
220 }