Protect SCM members in Instrument_name_engraver/Instrument_switch_engraver.
[lilypond/mpolesky.git] / lily / dynamic-align-engraver.cc
blob074569d63a14f2b20f11ed89d2959dd9365c140a
1 /*
2 This file is part of LilyPond, the GNU music typesetter.
4 Copyright (C) 2008--2010 Han-Wen Nienhuys <hanwen@lilypond.org>
7 LilyPond is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 LilyPond is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with LilyPond. If not, see <http://www.gnu.org/licenses/>.
21 #include <set>
23 #include "engraver.hh"
25 #include "axis-group-interface.hh"
26 #include "directional-element-interface.hh"
27 #include "item.hh"
28 #include "side-position-interface.hh"
29 #include "spanner.hh"
30 #include "stream-event.hh"
32 #include "translator.icc"
34 class Dynamic_align_engraver : public Engraver
36 TRANSLATOR_DECLARATIONS (Dynamic_align_engraver);
37 DECLARE_ACKNOWLEDGER (note_column);
38 DECLARE_ACKNOWLEDGER (dynamic);
39 DECLARE_END_ACKNOWLEDGER (dynamic);
41 protected:
42 virtual void stop_translation_timestep ();
44 private:
45 void create_line_spanner (Stream_event *cause);
46 Spanner* line_;
48 vector<Spanner*> ended_;
49 vector<Spanner*> started_;
50 vector<Grob*> scripts_;
51 vector<Grob*> support_;
53 set<Spanner*> running_;
56 Dynamic_align_engraver::Dynamic_align_engraver ()
58 line_ = 0;
61 ADD_ACKNOWLEDGER (Dynamic_align_engraver, dynamic);
62 ADD_ACKNOWLEDGER (Dynamic_align_engraver, note_column);
63 ADD_END_ACKNOWLEDGER (Dynamic_align_engraver, dynamic);
65 void
66 Dynamic_align_engraver::create_line_spanner (Stream_event* event)
68 if (!line_)
69 line_ = make_spanner ("DynamicLineSpanner",
70 event ? event->self_scm() : SCM_EOL);
73 void
74 Dynamic_align_engraver::acknowledge_end_dynamic (Grob_info info)
76 if (Spanner::has_interface(info.grob()))
77 ended_.push_back (info.spanner ());
80 void
81 Dynamic_align_engraver::acknowledge_note_column (Grob_info info)
83 support_.push_back (info.grob ());
86 void
87 Dynamic_align_engraver::acknowledge_dynamic (Grob_info info)
89 Stream_event *cause = info.event_cause ();
90 create_line_spanner (cause);
91 if (Spanner::has_interface(info.grob()))
92 started_.push_back (info.spanner ());
93 else if (info.item())
94 scripts_.push_back (info.item());
95 else
96 info.grob ()->programming_error ("Unknown dynamic grob.");
98 Axis_group_interface::add_element (line_, info.grob ());
100 if (cause)
102 if (Direction d = to_dir (cause->get_property ("direction")))
103 set_grob_direction (line_, d);
107 void
108 Dynamic_align_engraver::stop_translation_timestep ()
110 for (vsize i = 0; i < started_.size(); i++)
111 running_.insert (started_[i]);
112 for (vsize i = 0; i < ended_.size(); i++)
114 Spanner *sp = ended_[i];
116 set<Spanner*>::iterator it = running_.find (sp);
117 if (it != running_.end())
118 running_.erase (it);
119 else
120 started_[i]->programming_error ("Lost track of this dynamic spanner.");
123 bool end = line_ && running_.empty ();
124 Direction d = LEFT;
127 if (line_
128 && ((d == LEFT && !line_->get_bound (LEFT))
129 || (end && d == RIGHT && !line_->get_bound (RIGHT))))
131 vector<Spanner*> const &spanners =
132 (d == LEFT) ? started_ : ended_;
134 Grob *bound = 0;
135 if (scripts_.size())
136 bound = scripts_[0];
137 else if (spanners.size())
138 bound = spanners[0]->get_bound (d);
139 else
141 programming_error ("Started DynamicLineSpanner but have no left bound.");
142 bound = unsmob_grob (get_property ("currentMusicalColumn"));
145 line_->set_bound (d, bound);
148 while (flip (&d) != LEFT);
150 for (vsize i = 0; line_ && i < support_.size (); i++)
151 Side_position_interface::add_support (line_, support_[i]);
153 if (end)
154 line_ = 0;
156 ended_.clear ();
157 started_.clear ();
158 scripts_.clear ();
159 support_.clear ();
163 ADD_TRANSLATOR (Dynamic_align_engraver,
164 /* doc */
165 "Align hairpins and dynamic texts on a horizontal line",
167 /* create */
168 "DynamicLineSpanner ",
170 /* read */
171 "currentMusicalColumn ",
173 /* write */