]> git.donarmstrong.com Git - lilypond.git/blob - lily/metronome-engraver.cc
Break-alignable metronome marks: remove hardcoding of time signature.
[lilypond.git] / lily / metronome-engraver.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1998--2010 Jan Nieuwenhuizen <janneke@gnu.org>
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <cctype>
21 using namespace std;
22
23 #include "engraver.hh"
24
25 #include "context.hh"
26 #include "duration.hh"
27 #include "grob-array.hh"
28 #include "item.hh"
29 #include "stream-event.hh"
30 #include "text-interface.hh"
31
32 #include "translator.icc"
33
34 class Metronome_mark_engraver : public Engraver
35 {
36 public:
37   TRANSLATOR_DECLARATIONS (Metronome_mark_engraver);
38
39 protected:
40   Item *text_;
41   Grob *support_;
42
43   SCM last_duration_;
44   SCM last_count_;
45   SCM last_text_;
46
47   DECLARE_ACKNOWLEDGER (break_aligned);
48   
49 protected:
50   virtual void derived_mark () const;
51   void stop_translation_timestep ();
52   void process_music ();
53 };
54
55 Metronome_mark_engraver::Metronome_mark_engraver ()
56 {
57   text_ = 0;
58   support_ = 0;
59   last_duration_ = SCM_EOL;
60   last_count_ = SCM_EOL;
61   last_text_ = SCM_EOL;
62 }
63
64 void
65 Metronome_mark_engraver::derived_mark () const
66 {
67   scm_gc_mark (last_count_);
68   scm_gc_mark (last_duration_);
69   scm_gc_mark (last_text_);
70 }
71
72 void
73 Metronome_mark_engraver::acknowledge_break_aligned (Grob_info inf)
74 {
75   Grob *s = inf.grob ();
76   if (text_
77       && (s->get_property_data ("break-align-symbol")
78           == text_->get_property_data ("break-align-symbol")))
79     {
80       support_ = s;
81     }
82 }
83
84 void
85 Metronome_mark_engraver::stop_translation_timestep ()
86 {
87   if (text_)
88     {
89       if (!support_)
90         {
91           /*
92             Gardner Read "Music Notation", p.278
93
94             Align the metronome mark over the time signature (or the
95             first notational element of the measure if no time
96             signature is present in that measure).
97           */
98           Grob *mc = unsmob_grob (get_property ("currentMusicalColumn"));
99           text_->set_parent (mc, X_AXIS);
100         }
101       text_->set_object ("side-support-elements",
102                          grob_list_to_grob_array (get_property ("stavesFound")));
103       text_ = 0;
104       support_ = 0;
105     }
106 }
107
108 void
109 Metronome_mark_engraver::process_music ()
110 {
111   SCM count = get_property ("tempoUnitCount");
112   SCM duration = get_property ("tempoUnitDuration");
113   SCM text = get_property ("tempoText");
114
115   if ( ( (unsmob_duration (duration) && scm_is_number (count))
116         || Text_interface::is_markup (text) )
117       && !(ly_is_equal (count, last_count_)
118            && ly_is_equal (duration, last_duration_)
119            && ly_is_equal (text, last_text_)))
120     {
121       text_ = make_item ("MetronomeMark", SCM_EOL);
122
123       SCM proc = get_property ("metronomeMarkFormatter");
124       SCM result = scm_call_4 (proc,
125                                text,
126                                duration,
127                                count,
128                                context ()->self_scm ());
129
130       text_->set_property ("text", result);
131     }
132
133   last_duration_ = duration;
134   last_count_ = count;
135   last_text_ = text;
136 }
137
138
139
140 ADD_ACKNOWLEDGER (Metronome_mark_engraver, break_aligned);
141
142 ADD_TRANSLATOR (Metronome_mark_engraver,
143                 /* doc */
144                 "Engrave metronome marking.  This delegates the formatting"
145                 " work to the function in the @code{metronomeMarkFormatter}"
146                 " property.  The mark is put over all staves.  The staves are"
147                 " taken from the @code{stavesFound} property, which is"
148                 " maintained by @ref{Staff_collecting_engraver}.",
149
150                 /* create */
151                 "MetronomeMark ",
152
153                 /* read */
154                 "stavesFound "
155                 "metronomeMarkFormatter "
156                 "tempoUnitDuration "
157                 "tempoUnitCount "
158                 "tempoText "
159                 "tempoHideNote ",
160
161                 /* write */
162                 ""
163                 );