]> git.donarmstrong.com Git - lilypond.git/blob - lily/instrument-name-engraver.cc
* lily/instrument-name-engraver.cc (stop_translation_timestep):
[lilypond.git] / lily / instrument-name-engraver.cc
1 /*
2   instrument-name-engraver.cc -- implement Instrument_name_engraver
3
4   source file of the GNU LilyPond music typesetter
5
6   (c) 2000--2006 Han-Wen Nienhuys <hanwen@xs4all.nl>
7 */
8
9 #include "engraver.hh"
10 #include "bar-line.hh"
11 #include "system-start-delimiter.hh"
12 #include "side-position-interface.hh"
13 #include "align-interface.hh"
14 #include "axis-group-interface.hh"
15 #include "context.hh"
16 #include "text-interface.hh"
17 #include "grob-array.hh"
18
19 #include "translator.icc"
20
21 class Instrument_name_engraver : public Engraver
22 {
23   bool first_;
24 public:
25   TRANSLATOR_DECLARATIONS (Instrument_name_engraver);
26
27 protected:
28   Grob *text_;
29
30   virtual void create_text ();
31   virtual void initialize ();
32
33   DECLARE_ACKNOWLEDGER (bar_line);
34   DECLARE_ACKNOWLEDGER (axis_group);
35
36   void stop_translation_timestep ();
37   void process_music ();
38 };
39
40 Instrument_name_engraver::Instrument_name_engraver ()
41 {
42   text_ = 0;
43   first_ = true;
44 }
45
46 void
47 Instrument_name_engraver::initialize ()
48 {
49   context ()->set_property ("instrumentSupport", SCM_EOL);
50 }
51
52 void
53 Instrument_name_engraver::stop_translation_timestep ()
54 {
55   if (text_)
56     {
57       SCM support = get_property ("instrumentSupport");
58       text_->set_object ("side-support-elements",
59                          grob_list_to_grob_array (support));
60
61       /*
62         Hack to get texts on piano staves to disappear.
63        */
64       if (!text_->get_parent (Y_AXIS)
65           && scm_is_pair (support))
66         {
67           Axis_group_interface::add_element (unsmob_grob (scm_car (support)),
68                                              text_);
69         }
70       text_ = 0;
71     }
72
73   first_ = false;
74 }
75
76 void
77 Instrument_name_engraver::create_text ()
78 {
79   if (text_)
80     return;
81
82   SCM txt = get_property ("instrument");
83
84   if (now_mom () > Moment (0))
85     txt = get_property ("instr");
86   /*
87     UGH.
88   */
89   if (txt == SCM_EOL)
90     return;
91
92   text_ = make_item ("InstrumentName", SCM_EOL);
93
94   if (text_->get_property ("text") != txt)
95     text_->set_property ("text", txt);
96 }
97
98 void
99 Instrument_name_engraver::acknowledge_bar_line (Grob_info info)
100 {
101   (void) info;
102   create_text ();
103 }
104
105 void
106 Instrument_name_engraver::acknowledge_axis_group (Grob_info info)
107 {
108   /*
109     Ugh - typechecking for pedal and dynamic sucks.
110   */
111   if (dynamic_cast<Spanner *> (info.grob ())
112       && (info.grob ()->internal_has_interface (ly_symbol2scm ("dynamic-interface"))
113           || info.grob ()->internal_has_interface (ly_symbol2scm ("piano-pedal-interface"))))
114     return;
115
116   /*
117     Hang the instrument names on the staves, but not on the alignment
118     groups enclosing that staff. The alignment has no real location,
119     but is only a vehicle for the placement routine it contains, and
120     therefore the location of its refpoint won't be very useful.
121
122     We could also just use stavesFound, but lets keep this working
123     without staffs as well.
124   */
125   if (dynamic_cast<Spanner *> (info.grob ())
126       && ((Axis_group_interface::has_interface (info.grob ())
127            && Axis_group_interface::has_axis (info.grob (), Y_AXIS))))
128     {
129       if (!Align_interface::has_interface (info.grob ()))
130         {
131           SCM nl = scm_cons (info.grob ()->self_scm (),
132                              get_property ("instrumentSupport"));
133
134           context ()->set_property ("instrumentSupport", nl);
135         }
136     }
137 }
138
139 void
140 Instrument_name_engraver::process_music ()
141 {
142   /*
143     Also create text if barlines in other groups. This allows
144     a name to be attached to lyrics or chords.
145   */
146   if (scm_is_string (get_property ("whichBar"))
147       || first_)
148     create_text ();
149 }
150
151 #include "translator.icc"
152
153 ADD_ACKNOWLEDGER (Instrument_name_engraver, bar_line);
154 ADD_ACKNOWLEDGER (Instrument_name_engraver, axis_group);
155
156 ADD_TRANSLATOR (Instrument_name_engraver,
157                 /* doc */ " Prints the name of the instrument (specified by "
158                 " @code{Staff.instrument} and @code{Staff.instr}) "
159                 "at the left of the staff. ",
160                 /* create */ "InstrumentName",
161                 /* accept */ "",
162                 /* read */ "instrument instr",
163                 /* write */ "");
164
165 /****************************************************************/
166
167 class Vocal_name_engraver : public Instrument_name_engraver
168 {
169 public:
170   TRANSLATOR_DECLARATIONS (Vocal_name_engraver);
171   virtual void create_text ();
172 };
173
174 Vocal_name_engraver::Vocal_name_engraver ()
175 {
176 }
177
178 void
179 Vocal_name_engraver::create_text ()
180 {
181   if (text_)
182     return;
183
184   SCM txt = get_property ("vocalName");
185
186   if (now_mom () > Moment (0))
187     txt = get_property ("vocNam");
188
189   /*
190     UGH.
191   */
192   if (txt == SCM_EOL)
193     return;
194
195   text_ = make_item ("VocalName", SCM_EOL);
196
197   if (text_->get_property ("text") != txt)
198     text_->set_property ("text", txt);
199 }
200
201 ADD_ACKNOWLEDGER (Vocal_name_engraver, bar_line);
202 ADD_ACKNOWLEDGER (Vocal_name_engraver, axis_group);
203 ADD_TRANSLATOR (Vocal_name_engraver,
204                 /* doc */ " Prints the name of the a lyric voice (specified by "
205                 " @code{Staff.vocalName} and @code{Staff.vocNam}) "
206                 "at the left of the staff. ",
207                 /* create */ "VocalName",
208                 /* accept */ "",
209                 /* read */ "vocNam vocalName",
210                 /* write */ "");