lilypond-1.3.145
[lilypond.git] / lily / piano-pedal-engraver.cc
blob7f25a21dd30c51874851d33cca1740a75ae6341c
1 /*
2 piano-pedal-engraver.cc -- implement Piano_pedal_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 2000--2001 Jan Nieuwenhuizen <janneke@gnu.org>
7 */
9 #include "engraver.hh"
10 #include "musical-request.hh"
11 #include "grob.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"
20 class Piano_pedal_engraver : public Engraver
22 public:
23 VIRTUAL_COPY_CONS (Translator);
24 Piano_pedal_engraver ();
25 ~Piano_pedal_engraver ();
26 protected:
27 virtual void initialize ();
28 virtual bool try_music (Music*);
29 virtual void stop_translation_timestep ();
30 virtual void start_translation_timestep ();
31 virtual void acknowledge_grob (Grob_info);
32 virtual void create_grobs ();
34 private:
35 struct Pedal_info
37 char const * name_;
38 Span_req* start_req_l_;
39 Drul_array<Span_req*> req_l_drul_;
40 Item* item_p_;
44 Pedal_info *info_list_;
47 ADD_THIS_TRANSLATOR (Piano_pedal_engraver);
49 Piano_pedal_engraver::Piano_pedal_engraver ()
51 info_list_ = 0;
53 void
54 Piano_pedal_engraver::initialize ()
56 info_list_ = new Pedal_info[4];
57 Pedal_info *p = info_list_;
60 char * names [] = { "Sostenuto", "Sustain", "UnaCorda", 0 };
61 char **np = names ;
64 p->name_ = *np;
65 p->item_p_ = 0;
66 p->req_l_drul_[START] = 0;
67 p->req_l_drul_[STOP] = 0;
68 p->start_req_l_ = 0;
70 p++;
72 while (* (np ++));
75 Piano_pedal_engraver::~Piano_pedal_engraver ()
77 delete[] info_list_;
81 Urg: Code dup
82 I'm a script
84 void
85 Piano_pedal_engraver::acknowledge_grob (Grob_info info)
87 for (Pedal_info*p = info_list_; p && p->name_; p ++)
89 if (p->item_p_)
91 if (Rhythmic_head::has_interface (info.elem_l_))
93 Side_position_interface::add_support (p->item_p_, info.elem_l_);
95 if (Side_position_interface::get_axis (p->item_p_) == X_AXIS
96 && !p->item_p_->parent_l (Y_AXIS))
97 p->item_p_->set_parent (info.elem_l_, Y_AXIS);
99 if (Stem::has_interface (info.elem_l_))
101 Side_position_interface::add_support (p->item_p_,info.elem_l_);
107 bool
108 Piano_pedal_engraver::try_music (Music *m)
110 if (Span_req * s = dynamic_cast<Span_req*> (m))
112 for (Pedal_info*p = info_list_; p->name_; p ++)
114 if (scm_equal_p (s->get_mus_property ("span-type"),
115 ly_str02scm (p->name_))==SCM_BOOL_T)
117 p->req_l_drul_[s->get_span_dir ()] = s;
118 return true;
122 return false;
125 void
126 Piano_pedal_engraver::create_grobs ()
128 for (Pedal_info*p = info_list_; p && p->name_; p ++)
130 if (p->item_p_ || ! (p->req_l_drul_[STOP] || p->req_l_drul_[START]))
131 continue;
133 SCM s = SCM_EOL;
134 SCM strings = get_property (("pedal" + String (p->name_) + "Strings").ch_C ());
135 if (scm_ilength (strings) < 3)
136 continue;
138 if (p->req_l_drul_[STOP] && p->req_l_drul_[START])
140 if (!p->start_req_l_)
142 p->req_l_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: %s", p->name_));
144 else
146 s = gh_cadr (strings);
148 p->start_req_l_ = p->req_l_drul_[START];
150 else if (p->req_l_drul_[STOP])
152 if (!p->start_req_l_)
154 p->req_l_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: %s", p->name_));
156 else
158 s = gh_caddr (strings);
160 p->start_req_l_ = 0;
162 else if (p->req_l_drul_[START])
164 p->start_req_l_ = p->req_l_drul_[START];
165 s = gh_car (strings);
168 if (gh_string_p (s))
170 String propname = String (p->name_) + "Pedal";
171 p->item_p_ = new Item (get_property (propname.ch_C ()));
172 p->item_p_->set_grob_property ("text", s);
174 announce_grob (p->item_p_,
175 p->req_l_drul_[START]
176 ? p->req_l_drul_[START]
177 : p->req_l_drul_[STOP]);
179 p->req_l_drul_[START] = 0;
180 p->req_l_drul_[STOP] = 0;
184 void
185 Piano_pedal_engraver::stop_translation_timestep ()
187 Item * sustain = 0;
188 for (Pedal_info*p = info_list_; p->name_; p ++)
190 if (p->name_ == String ("Sustain"))
191 sustain = p->item_p_;
194 for (Pedal_info*p = info_list_; p->name_; p ++)
196 if (p->item_p_)
198 Side_position_interface::add_staff_support (p->item_p_);
201 Hmm.
203 if (p->name_ != String ("Sustain"))
205 if (sustain)
207 Side_position_interface::add_support (p->item_p_,sustain);
210 typeset_grob (p->item_p_);
212 p->item_p_ = 0;
216 void
217 Piano_pedal_engraver::start_translation_timestep ()
219 for (Pedal_info*p = info_list_; p->name_; p ++)
221 p->req_l_drul_[STOP] = 0;
222 p->req_l_drul_[START] = 0;